var qs = require('querystring');

var surpriseRoutes = {
    1: [2,6],
    2: [3,7],
    3: [2,4,8],
    4: [3,5,9],
    5: [4,10],
    6: [7,11],
    7: [6,8,12],
    8: [7,9,13],
    9: [8,10,14],
    10:[5,9,15],
    11:[6,12],
    12:[7,11,13],
    13:[8,12,14],
    14:[9,13,15],
    15:[1]
};

var PassCardId = 0;     // 跑商,西域夺宝 通过ID
var DigTreasureDoorId = 2; // 地下宝藏通道的ID

var batModMap = {   
    'DUPLICATE' : 0,   //副本                 
    'TOWER'     : 1,   //勇闯重楼         
    'KILL'      : 2,   //过关斩将       
    'PVP'       : 3,   //
    'TOMB'      : 4,   //古墓宝藏
    'DIGTREASURE' : 5, // 地下宝藏
    'MYBATTLE'  : 6,   // 个人战役
};

// 迎接财神消息  
function WealthMessage(){
    this.messages = [];
}

WealthMessage.prototype = {
    get : function() {
        return this.messages; 
    },

    insert : function(message) {
        if( this.messages.length >= 4 ) {
            this.messages.shift(); 
        } 

        this.messages.push(message);
    },
}

exports.WealthMessage = WealthMessage;

exports.online_reward = function(player, req, resp, onHandled){
    do{
        if( isNaN(req.args.time) ) {
            resp.code = 1; resp.desc = 'no valid args'; break;
        }

        var time = +req.args.time;
        var onlineConf = gConfOnlineReward[time];
        if( !onlineConf ) {
            resp.code = 1; resp.desc = 'invalid time'; break;
        }

        var user = player.user;
        if( user.activity.online_timer >= time ) {
            resp.code = 1; resp.desc = 'got'; break;
        }

        var awards = [];
        if( onlineConf.Award1 ) {
            awards.push(onlineConf.Award1);
        }

        user.status.gold += +onlineConf.Gold;
        user.status.honor += +onlineConf.Honor;

        user.activity.online_timer = time;

        player.markDirty('status.gold');
        player.markDirty('status.honor');
        player.markDirty('activity.online_timer');


        resp.data.gold = onlineConf.Gold;
        resp.data.honor = onlineConf.Honor;
        resp.data.awards = player.addAwards(awards);

    }while(false);
    onHandled();
}

exports.system_reward = function(player, req, resp, onHandled){
    do {
        if( isNaN(req.args.id) ) {
            resp.code = 1; resp.desc = 'no valid args'; break;
        }

        var id = +req.args.id;
        var systemRewardConf = gConfSystemReward[id];
        var globalId = +gConfGlobalServer.SystemRewardId;
        if( !systemRewardConf || !globalId || id != globalId ) {
            resp.code = 1; resp.desc = 'invalid id'; break;
        }

        if( player.user.info.create > gConfGlobalServer.SystemRewardTime ) {
            resp.code = 1; resp.desc = 'create late'; break;
        }

        var user = player.user;
        var activity = user.activity;
        if( id == activity.system_reward ) {
            resp.code = 1; resp.desc = 'got'; break;
        }

        var awards = [];
        for( var i = 1; i < 4; i++) {
            var award = systemRewardConf['Award' + i];
            if( !award ) {
                continue;    
            } 

            awards.push(award);
        } 

        awards = player.addAwards(awards);
        activity.system_reward = id;
        player.markDirty('activity.system_reward');

        resp.data.awards = awards;
    }while(false);

    onHandled();
}

exports.leveltop_reward = function(player, req, resp, onHandled){
    do {
        if( isNaN(req.args.level) ) {
            resp.code = 1; resp.desc = 'invalid args'; break;
        }
        
        var now = common.getTime();
        var confActivities = gConfActivities.leveltop;
        if( now < confActivities.StartTime || now > confActivities.EndTime ) {
            resp.code = 1; resp.desc = 'invalid time'; break;
        }
        
        var level = +req.args.level;
        var confAvLevelTop = gConfAvLevelTop[level];
        if( !confAvLevelTop ) {
            resp.code = 1; resp.desc = 'invalid args'; break;
        }

        var user = player.user;
        if( level > user.status.level ) {
            resp.code = 1; resp.desc = 'not reach'; break;
        }

        var activity = user.activity;
        if( level <= activity.level_top ) {
            resp.code = 1; resp.desc = 'got'; break;
        }

        activity.level_top = level; 
        player.markDirty('activity.level_top');
        
        var awards =[];
        for( var i = 1; i < 4; i++) {
            var award = confAvLevelTop['Award'+i];
            if( !award ) {
                continue;    
            } 

            awards.push(award);
        }

        awards = player.addAwards(awards);
        
        resp.data.awards = awards;
    }while(false);

    onHandled();
}

exports.get_wheel_reward = function(player, req, resp, onHandled) {
    do {
        var activitySchedule = findActivitySchedule('wheel');
        if( !activitySchedule ) {
            resp.code = 1; resp.desc = 'not open'; break;
        }

        var luckyWheelConf = gConfAvLuckyWheel[activitySchedule.conf];

        var user = player.user;
        if( !user.wheel.star ) {
            resp.code = 1;  resp.desc = 'no awards'; break;
        }

        var awards = [];
        var star = user.wheel.star;
        for ( var i=1; i<=star; i++ ) {
            var award = luckyWheelConf[i].Award1;
            if( award ) {
                awards.push(award);
            }
        }   

        user.wheel.star = 0;
        player.markDirty('wheel.star');

        user.wheel.star_cash = 0;
        player.markDirty('wheel.star_cash');

        user.wheel.star_cash_total = 0;
        player.markDirty('wheel.star_cash_total');

        awards = player.addAwards(awards);
        resp.data.awards = awards;

    }while(false);
 
    onHandled();
}

exports.start_wheel = function(player, req, resp, onHandled ) {
    do {
        var isCash = req.args.cash ? true : false;
        var user = player.user;
        var wheel = user.wheel;

        var activitySchedule = findActivitySchedule('wheel');
        if( !activitySchedule ) {
            resp.code = 1; resp.desc = 'not open'; break;
        }

        var luckyWheelConf = gConfAvLuckyWheel[activitySchedule.conf];

        if( !luckyWheelConf[wheel.star+1] ) {
            resp.code = 1; resp.desc = 'not allowed start'; break;
        }

        var vipAddLimit = 0;
        if( gConfVip[user.status.vip] ) {
            vipAddLimit = gConfVip[user.status.vip].WheelDailyLimit;
        }

        var freeLimit = gConfGlobal.WheelDailyLimit + vipAddLimit; 
        if( !isCash && wheel.free >= freeLimit )  {
            resp.code = 1; resp.desc = 'not enough free time'; break;
        }

        var cashCost = 0;
        if( isCash ) {
            cashCost = gConfGlobal.WheelCashBase + gConfGlobal.WheelCashAdd * wheel.star_cash_total; 
            if( cashCost > gConfGlobal.WheelCashMax ) {
                cashCost = gConfGlobal.WheelCashMax; 
            }

            if (!player.costResource('cash', cashCost, wheel.star, wheel.star_cash)) {
                resp.code = 1; resp.desc = 'not enough cash'; break;
            }
        }
        
        var star_cash = wheel.star_cash;
        var star = wheel.star;

        if( isCash ) {
            star_cash += 1;
        }

        var starRate = 0;
        if( wheel.first_start ) {
            for( var i=star+1; luckyWheelConf[i]; i++ ) {
                starRate = parseInt(luckyWheelConf[i].FirstRate);
                if( isCash ) {
                    starRate += star_cash * luckyWheelConf[i].AddRate;
                }

                if( common.randRange(1, 100) > starRate ) {
                    break;
                }

                star += 1;
                star_cash = 0;
            }
            
            wheel.first_start = 0;
            player.markDirty('wheel.first_start');

        }else {
            for( var i=star+1; luckyWheelConf[i]; i++ ) {
                starRate = starRate = parseInt(luckyWheelConf[i].NormalRate);
                if( isCash ) {
                    starRate +=  star_cash * luckyWheelConf[i].AddRate;
                }
                
                if( common.randRange(1, 100) > starRate ) {
                    break;
                }

                star += 1;
                star_cash = 0;
            }
        }

        //特殊奖励
        if( luckyWheelConf[star].Award2 ) {
            resp.data.awards = player.addAwards([luckyWheelConf[star].Award2]);
        }

        wheel.star = star;
        player.markDirty('wheel.star');

        wheel.star_cash = star_cash;
        player.markDirty('wheel.star_cash');

        if( isCash ) {
            wheel.star_cash_total += 1;
            player.markDirty('wheel.star_cash_total');
        }else {
            user.wheel.free += 1;
            player.markDirty('wheel.free');
        }

        resp.data.star = wheel.star;

    }while(false);

    onHandled();
}

exports.invest_join = function(player, req, resp, onHandled ) {
    do {
        if( isNaN(req.args.id) ) {
            resp.code = 1; resp.desc = 'invalid args'; break;
        }

        var id = parseInt(req.args.id);
        
        var activitySchedule = findActivitySchedule('invest');
        if( !activitySchedule ) {
            resp.code = 1; resp.desc = 'invalid time'; break;
        }

        var user = player.user;
        if( user.invest.invested ) {
            resp.code = 1; resp.desc = 'not allowed invest again'; break;
        }

        var investConf = gConfAvInvest[id];
        if( !investConf ) {
            resp.code = 1; resp.desc = 'invalid invest id'; break;
        }
        var cashCost = investConf[1].InvestCash;
        if (!player.costResource('cash', cashCost, id)) {
            resp.code = 1; resp.desc = 'not enough cash'; break;
        }
        
        user.invest.time = common.getDateString();
        player.markDirty('invest.time');

        user.invest.invested = id;
        player.markDirty('invest.invested');

        resp.data.cash = -cashCost;

    }while(false);

    onHandled();
}

exports.invest_get = function(player, req, resp, onHandled ) {
    do {
        if( isNaN(req.args.day) ) {
            resp.code = 1; resp.desc = 'invalid args'; break;
        }

        var day = parseInt(req.args.day);

        var user = player.user;
        var invest = user.invest;
        if( !invest.invested ) {
            resp.code = 1; resp.desc = 'not invest'; break;
        }

        var investConf = gConfAvInvest[invest.invested];
        var investDayConf = investConf[day];
        if( !investDayConf ) {
            resp.code = 1; resp.desc = 'invalid day'; break;
        }

        if( day <= invest.got ) {
            resp.code = 1; resp.desc = 'invalid day'; break;
        }
        
        var dayPassed = common.getDayPassed(invest.time) - 1;
        if( dayPassed < investConf.InvestDay ) {
            resp.code = 1; resp.desc = 'day not reach'; break;
        }

        user.invest.got = day;
        player.markDirty('invest.got');
        
        player.alterResource('cash', investDayConf.Cash, invest.invested, day);
        player.alterResource('gold', investDayConf.Gold, invest.invested, day);
        player.alterResource('food', investDayConf.Food, invest.invested, day);

        resp.data.cash = investDayConf.Cash;
        resp.data.gold = investDayConf.Gold;
        resp.data.food = investDayConf.Food;

    }while(false);

    onHandled();
}

exports.get_limit_buy = function(player, req, resp, onHandled) {
    var activitySchedule = findActivitySchedule('limitbuy');
    if( !activitySchedule ) {
        resp.code = 1; resp.desc = 'not open'; 
        onHandled();
        return;
    }

    requestWorld(req, resp, function(){
        onHandled();
    });
}

exports.do_limit_buy = function(player, req, resp, onHandled) {
    var user = player.user;
    var id = parseInt(req.args.id);
    var limitBuyConf = gConfAvLimitBuy[id];
    var cashCost = 0;
    do {
        var activitySchedule = findActivitySchedule('limitbuy');
        if( !activitySchedule ) {
            resp.code = 1; resp.desc = 'not open'; break;
        }

        if( !limitBuyConf ) {
            resp.code = 1; resp.desc = 'invalid id'; break;
        }

        var bought =  user.activity.limit_buy[id] || 0;
        if( bought >= limitBuyConf.PersonLimit ) {
            resp.code = 1; resp.desc = 'no more to buy'; break;
        }

        cashCost = limitBuyConf.Cash;
        if( cashCost > user.status.cash ) {
            resp.code = 1; resp.desc = 'no more cash'; break;
        }
    }while(false);

    if( resp.code != 0 ) {
        onHandled();
        return;
    }

    requestWorld(req, resp, function(){
        if( resp.code == 0 && !resp.data.over ) {
            var bought =  user.activity.limit_buy[id] || 0;
            user.activity.limit_buy[id] = bought + 1;
            player.markDirty('activity.limit_buy.'+id);

            player.costResource('cash', cashCost, id);
            var awards = [
                limitBuyConf.Award1, 
                limitBuyConf.Award2,
                limitBuyConf.Award3,
                limitBuyConf.Award4, 
                limitBuyConf.Award5
            ];

            resp.data.cash = -cashCost;
            resp.data.awards = player.addAwards(awards);
        }
        onHandled();
    });
}

exports.surprise_go = function(player, req, resp, onHandled) {
    do{ 
        var activitySchedule = findActivitySchedule('surprise');
        if( !activitySchedule ) {
            resp.code = 1; resp.desc = 'not open'; break;
        }

        var user = player.user;

        var maxTime = gConfGlobal.SurpriseDailyLimit;
        if( user.status.vip ) {
            maxTime += gConfVip[user.status.vip].SurpriseAdd;
        }

        if( user.surprise.free >= maxTime ) {
            resp.code = 1; resp.desc = 'no more time'; break;
        }

        var ten = req.args.ten ? 1 : 0;

        var freeTime  = 0;
        var cashTime = 0;
        var freeLeft = gConfGlobal.SurpriseDailyFreeLimit - user.surprise.free;

        if( ten ) {
            freeTime = freeLeft<0 ? 0 : freeLeft;
            cashTime = 10 - freeTime;
        }else{
            if( freeLeft <= 0 ) {
                freeTime = 0;
                cashTime = 1;
            }else{
                freeTime = 1;
                cashTime = 0;
            }
        }

        if( cashTime > 0 ) {
            var canCashTime = parseInt(user.status.cash/gConfGlobal.SurpriseCash);
            cashTime = cashTime>canCashTime ? canCashTime : cashTime;
        }

        if( (user.surprise.free + cashTime + freeTime) > maxTime ) {
            cashTime = maxTime - user.surprise.free - freeTime;
        }

        var step = cashTime + freeTime;
        if( step <= 0 ) { 
            resp.code = 1; resp.desc = 'no more cash or free'; break;
        }

        var nowRoutes = [];
        var nowGrid = user.surprise.grid;
        var grids = [];

        for( var i=1; i<=step; i++ ) {
            nowRoutes = surpriseRoutes[nowGrid];
            nowGrid = common.randArray(nowRoutes);

            if( nowGrid == 1 ) {
                nowRoutes = surpriseRoutes[nowGrid];
                nowGrid = common.randArray(nowRoutes);
            }

            grids.push(nowGrid);
        }

        var avSurpriseConf = null; 
        var awards = [];
        var surpriseConf = gConfAvSurprise[activitySchedule.conf];
        for( var i=1; i<=step; i++ ) {
            avSurpriseConf = surpriseConf[grids[i-1]];
            if( !avSurpriseConf ) {
                break;
            }
            awards.push(avSurpriseConf.Award1);
        }

        if( !avSurpriseConf ) {
            resp.code = 1; resp.desc = 'invalid grid'; break;
        }
        
        var cashCost = cashTime * gConfGlobal.SurpriseCash; 
        if( cashCost > 0 ) {
            if (!player.costResource('cash', cashCost, user.surprise.grid, ten)) {
                resp.code = 1; resp.desc = 'not enough cash'; break;
            }
        }

        user.surprise.free += step; 
        user.surprise.grid = nowGrid;
        player.markDirty('surprise');

        resp.data.cash = -cashCost;
        resp.data.grid = grids;

        resp.data.awards = player.addAwards(awards);

    }while(false);

    onHandled();
}

exports.get_charge = function(player, req, resp, onHandled){
    do {
        var activitySchedule = findActivitySchedule('charge');
        if( !activitySchedule ) {
            resp.code = 1; resp.desc = 'not open'; break;
        }

        var user = player.user;

        if( user.activity.charge.time != activitySchedule.time ) {
            user.activity.charge = {
                'cash':0,          
                'time': activitySchedule.time,
                'got' : {
                }, 
            };
            player.markDirty('activity.charge');
        }

        resp.data.charge = user.activity.charge;
    }while(false);

    onHandled();
}

exports.gentry_get = function(player, req, resp, onHandled){
    do {
        var now = common.getTime();
        var activitiesConf = gConfActivities.gentry;
        if( !activitiesConf ) {
            resp.code = 1; resp.desc = 'no gentry'; break;
        }

        if( (now < activitiesConf.StartTime - 10) || (now > activitiesConf.EndTime + 10) ) {
            resp.code = 1; resp.desc = 'invalid time'; break;
        }

        var user = player.user;
        if( user.status.level < activitiesConf.OpenLevel ) {
            resp.code = 1; resp.desc = 'level not reach'; break;
        }

        if( user.activity.gentry.time != activitiesConf.StartTime ) {
            user.activity.gentry = {
                'cash': 0,
                'time': activitiesConf.StartTime,
                'got' : 0, 
            };
            player.markDirty('activity.gentry');
        }

        resp.data.gentry = user.activity.gentry;

    }while(false);

    onHandled();
}

exports.get_gentry_reward = function(player, req, resp, onHandled){
    do {
        var now = common.getTime();
        var activitiesConf = gConfActivities.gentry;
        if( !activitiesConf ) {
            resp.code = 1; resp.desc = 'no gentry'; break;
        }

        if( (now < activitiesConf.StartTime - 10) || (now > activitiesConf.EndTime + 10) ) {
            resp.code = 1; resp.desc = 'invalid time'; break;
        }

        var user = player.user;
        var gentry = user.activity.gentry;
        if( gentry.got == 1 ) {
            resp.code = 1; resp.desc = 'got'; break;
        }

        if( user.status.level < activitiesConf.OpenLevel ) {
            resp.code = 1; resp.desc = 'level not reach'; break;
        }

        if( gentry.cash < 20000 ) {
            resp.code = 1; resp.desc = 'not enough gentry cash'; break;
        }
        
        gentry.got = 1;
        player.markDirty('activity.gentry.got');

        resp.data.awards = player.addAwards([['material', 76, 1]]);

    }while(false);

    onHandled();
}

exports.charge_reward = function(player, req, resp, onHandled){
    do {
        if( isNaN(req.args.id) ) {
            resp.code = 1; resp.desc = 'invalid args'; break;
        }
        
        var rewardCashId = parseInt(req.args.id);
        var activitySchedule = findActivitySchedule('charge');
        if( !activitySchedule ) {
            resp.code = 1; resp.desc = 'not open'; break;
        }

        if( !gConfAvCharge[activitySchedule.conf][rewardCashId] ) {
            resp.code = 1; resp.desc = 'id error'; break;
        }

        var user = player.user;
        
        var charge = user.activity.charge;
        var chargedCash = +charge.cash;
        if( chargedCash < rewardCashId  ) {
            resp.code = 1; resp.desc = 'not enough cash'; break;
        }
        
        var got = charge.got;
        if( !(rewardCashId in got) ) {
            got[rewardCashId] = 0; 
        }        
        
        var canGotTime = 1;
        var avChargeConf = gConfAvCharge[activitySchedule.conf][rewardCashId];
        if( avChargeConf.IsRepeat ) {
            canGotTime = parseInt(chargedCash / rewardCashId); 
        }

        if( got[rewardCashId] >= canGotTime ) {
            resp.code = 1; resp.desc = 'have got'; break;
        } 

        got[rewardCashId] += 1;
        player.markDirty(util.format('activity.charge.got.%d', rewardCashId));

        var awards =[];
        for( var i = 1; i < 100; i++) {
            var award = avChargeConf['Award'+i];
            if( !award ) {
                continue;    
            } 

            awards.push(award);
        }

        awards = player.addAwards(awards);
        
        resp.data.awards = awards;
    }while(false);

    onHandled();
}

exports.get_offline_xp = function(player, req, resp, onHandled) {
    do{ 
        var useCash = req.args.cash ? 1 : 0;

        var user = player.user;

        var now = common.getTime();
        var offline_xp = user.activity.offline_xp;
        var passedHour = Math.floor((now - offline_xp.time + 10)/3600);

        var maxHour = gConfGlobal.OfflineXpHourLimit;
        if( offline_xp.vip ) {
            maxHour += gConfVip[offline_xp.vip].OfflineXpHour;
        }

        if( passedHour >= maxHour ) {
            passedHour = maxHour;
        }

        if( passedHour <= 0 ) {
            resp.code = 1; resp.desc = 'no enough hour'; break;
        }

        if( !gConfLevel[offline_xp.level] ) {
            resp.code = 1; resp.desc = 'level error'; break;
        }

        var addXp = gConfLevel[offline_xp.level].OfflineXp * passedHour;
        
        var cashCost = 0;
        if( useCash ) {
            cashCost = passedHour * gConfGlobal.OfflineXpCashHour;
            if( !player.costResource('cash', cashCost) ) {
                resp.code = 1; resp.desc = 'no enough cash'; break;
            }

            addXp *= gConfGlobal.OfflineXpCashFactor;
        }

        player.addXp(addXp);

        offline_xp.time = now;
        offline_xp.vip = user.status.vip;
        offline_xp.level = user.status.level;

        player.markDirty('activity.offline_xp');

        resp.data.cash = -cashCost;
        resp.data.xp = addXp;
        resp.data.level = user.status.level;
        resp.data.offline_xp = offline_xp;

    }while(false);

    onHandled();
}

exports.wish = function(player, req, resp, onHandled) {
    do{ 
        var now = common.getTime();
        var confActivities = gConfActivities.wish;
        if( now < confActivities.StartTime-30 || now > confActivities.EndTime+30 ) {
            resp.code = 1; resp.desc = 'invalid time'; break;
        }

        var user = player.user;
        if( user.status.level < confActivities.OpenLevel ) {
            resp.code = 1; resp.desc = 'level not reach'; break;
        }

        if( user.activity.wished == 1 ) {
            resp.code = 1; resp.desc = 'have wished'; break;
        }

        var cashCost = gConfGlobal.WishCash;
        if( !player.costResource('cash', cashCost) ) {
            resp.code = 1; resp.desc = 'not enough cash'; break;
        }

        var weights = {};
        for( var id in gConfAvWish ) {
            weights[id] = gConfAvWish[id].Weight;
        }

        user.activity.wished = 1; 
        player.markDirty('activity.wished');

        var randId = common.wRand(weights);
        var award = gConfAvWish[randId].Award1;
        var awardType = award[0];
        var awardId = award[1];
        if( awardType == 'card' ) {
            if( ((awardId in user.role_card) && user.role_card[awardId] > 0) || (awardId in user.role) ) {
                weights[randId] = 0;
                randId = common.wRand(weights);
                award = gConfAvWish[randId].Award1;
            }
        }

        resp.data.awards = player.addAwards([award]);
        resp.data.cash = -cashCost;
    }while(false);

    onHandled();
}

exports.buy_feed = function(player, req, resp, onHandled) {
    do {
        var now = common.getTime();
        var activitySchedule = findActivitySchedule('feed');
        if( !activitySchedule ) {
            resp.code = 1; resp.desc = 'not open'; break;
        }

        var confActivities = gConfActivities.feed;
        var user = player.user;
        if( user.status.level < confActivities.OpenLevel ) {
            resp.code = 1; resp.desc = 'level not reach'; break;
        }
        
        if( isNaN(req.args.id) || isNaN(req.args.num) || !gConfMaterial[req.args.id] ) {
            resp.code = 1; resp.desc = 'no valid args'; break;
        }

        if( (+req.args.num) < 1 ) {
            resp.code = 1; resp.desc = 'no valid args'; break;
        }

        var id = +req.args.id;
        var num = Math.round(req.args.num);

        var feedConf = gConfAvFeed[id];
        var materialConf = gConfMaterial[id];
        if( !feedConf || !materialConf ) {
            resp.code = 1; resp.desc = 'invalid id'; break;
        }
        
        var cashCost = feedConf.Cash * num;
        if( !player.costResource('cash', cashCost, id, num) ) {
            resp.code = 1; resp.desc = 'not enough cash'; break;
        }

        player.addInventory('material', id, num);

        resp.data.cash = -cashCost;

    }while(false);

    onHandled();
}

exports.get_yellow_diamond = function(player, req, resp, onHandled) {
    //黄钻抽奖
    do {
        var now = common.getTime();
        var confActivities = gConfActivities.yellowdiamond;
        if( (now < confActivities.StartTime - 10) || (now > confActivities.EndTime + 10) ) {
            resp.code = 1; resp.desc = 'invalid time'; break;
        }

        var user = player.user;
        if( user.status.level < confActivities.OpenLevel ) {
            resp.code = 1; resp.desc = 'level not reach'; break;
        }
        
        var diamondActivity = user.activity.yellow_diamond;
        if( !diamondActivity || diamondActivity.time != confActivities.StartTime ) {
            diamondActivity = {
                'time' : confActivities.StartTime,
                'opened' : 0,
                'got': {},
            }
            user.activity.yellow_diamond = diamondActivity;
            player.markDirty('activity.yellow_diamond');
        }

        resp.data.yellow_diamond = diamondActivity;

    }while(false);

    onHandled();
}

exports.get_yellow_diamond_reward = function(player, req, resp, onHandled) {
    //黄钻抽奖
    do {
        var now = common.getTime();
        var confActivities = gConfActivities.yellowdiamond;
        if( (now < confActivities.StartTime - 10) || (now > confActivities.EndTime + 10) ) {
            resp.code = 1; resp.desc = 'invalid time'; break;
        }

        var user = player.user;
        if( user.status.level < confActivities.OpenLevel ) {
            resp.code = 1; resp.desc = 'level not reach'; break;
        }
        
        var diamondActivity = user.activity.yellow_diamond;
        if( !diamondActivity || diamondActivity.time != confActivities.StartTime ) {
            resp.code = 1; resp.desc = 'no activity'; break;
        }
        
        /*
        // 老版
        if( !player.addInventory('material', 66, -1) ) {
            resp.code = 1; resp.desc = 'no more material'; break;
        }

        var weights = {};
        for( var id in gConfAvYellowDiamond ) {
            weights[id] = gConfAvYellowDiamond[id].Weight;
        }

        var id = common.wRand(weights);
        var avYellowDiamondConf = gConfAvYellowDiamond[id];

        var awards = player.addAwards([avYellowDiamondConf.Award1]);

        resp.data.id = id;
        resp.data.awards = awards;
        resp.data.material = {'66': -1};
        */
        
        if( isNaN(req.args.id) ) {
            resp.code = 1; resp.desc = 'invalid id'; break;
        }

        var id = +req.args.id;
        var diamondRoleConf = gConfAvYellowDiamondRole[id];
        if( !diamondRoleConf ) {
            resp.code = 1; resp.desc = 'invalid id'; break;
        }
        
        if( !player.addInventory('material', 66, -diamondRoleConf.Diamond) ) {
            resp.code = 1; resp.desc = 'not enough diamond'; break;
        }
        
        var awards = player.addAwards([diamondRoleConf.Award1]);

        resp.data.material = {'66': -diamondRoleConf.Diamond};
        resp.data.awards = awards;
    }while(false);

    onHandled();
}

exports.get_yellow_charge_reward = function(player, req, resp, onHandled){
    // 黄钻特惠
    do {
        if( isNaN(req.args.id) ) {
            resp.code = 1; resp.desc = 'invalid args'; break;
        }
        
        var rewardOpenedId = parseInt(req.args.id);
        if( !gConfAvYellowCharge[rewardOpenedId] ) {
            resp.code = 1; resp.desc = 'id error'; break;
        }

        var now = common.getTime();
        var activitiesConf = gConfActivities.yellowcharge;
        if( !activitiesConf ) {
            resp.code = 1; resp.desc = 'no yellow opened'; break;
        }

        if( (now < activitiesConf.StartTime - 10) || (now > activitiesConf.EndTime + 10) ) {
            resp.code = 1; resp.desc = 'invalid time'; break;
        }
        
        var user = player.user;
        if( user.status.level < activitiesConf.OpenLevel ) {
            resp.code = 1; resp.desc = 'level not reach'; break;
        }

        var yellowDiamond = user.activity.yellow_diamond;
        var yellowDiamondOpened = yellowDiamond.opened; 
        if( yellowDiamondOpened < rewardOpenedId  ) {
            resp.code = 1; resp.desc = 'not enough opened'; break;
        }
        
        var got = yellowDiamond.got;
        if( !(rewardOpenedId in got) ) {
            got[rewardOpenedId] = 0; 
        }        
        
        var canGotTime = 1;
        var avYellowChargeConf = gConfAvYellowCharge[rewardOpenedId];
        if( avYellowChargeConf.IsRepeat ) {
            canGotTime = parseInt(yellowDiamondOpened / rewardOpenedId); 
        }

        if( got[rewardOpenedId] >= canGotTime ) {
            resp.code = 1; resp.desc = 'have got'; break;
        } 

        got[rewardOpenedId] += 1;
        player.markDirty(util.format('activity.yellow_diamond.got.%d', rewardOpenedId));

        var awards =[];
        for( var i = 1; i < 1000; i++) {
            var award = avYellowChargeConf['Award'+i];
            if( !award ) {
                continue;    
            } 

            awards.push(award);
        }

        awards = player.addAwards(awards);
        
        resp.data.awards = awards;
    }while(false);

    onHandled();
}

exports.get_five_role_reward = function(player, req, resp, onHandled){
    do {
        var activitySchedule = findActivitySchedule('fiverole');
        if( !activitySchedule ) {
            resp.code = 1; resp.desc = 'not open'; break;
        }

        var user = player.user;
        var activitiesConf = gConfActivities.fiverole;
        if( user.status.level < activitiesConf.OpenLevel ) {
            resp.code = 1; resp.desc = 'level not reach'; break;
        }

        if( user.activity.five_role_reward ) {
            resp.code = 1; resp.desc = 'have got'; break;
        }

        var fiveRoleIds = gConfGlobal.FiveRoleIds.split(':');
        var haveReward = true;
        for( var i = 0, len = fiveRoleIds.length; i < len; i++ ) {
            var roleId = +fiveRoleIds[i];
            if( !((roleId in user.role) || (roleId in user.role_card)) ) {
                haveReward = false; 
                break;
            } 
        }

        if( !haveReward ) {
            resp.code = 1; resp.desc = 'no reward'; break;
        }

        user.activity.five_role_reward = 1;
        player.markDirty('activity.five_role_reward');

        resp.data.awards = player.addAwards([['user', 'food', 10000]]);
    }while(false);

    onHandled();
}

exports.get_tower_reward = function(player, req, resp, onHandled){
    do {
        if( isNaN(req.args.floor) || !gConfAvTower[req.args.floor] ) {
            resp.code = 1; resp.desc = 'invalid args'; break;
        }
        
        var rewardFloor = parseInt(req.args.floor);

        var activitySchedule = findActivitySchedule('tower');
        if( !activitySchedule ) {
            resp.code = 1; resp.desc = 'not open'; break;
        }

        var user = player.user;
        var activitiesConf = gConfActivities.tower;
        if( user.status.level < activitiesConf.OpenLevel ) {
            resp.code = 1; resp.desc = 'level not reach'; break;
        }
        
        if( user.tower.highest[1] < rewardFloor ) {
            resp.code = 1; resp.desc = 'floor not reach'; break;
        }

        var rewardGotFloor = user.activity.tower;
        if( rewardFloor <= rewardGotFloor ) {
            resp.code = 1; resp.desc = 'have got'; break;
        }

        user.activity.tower = rewardFloor;
        player.markDirty('activity.tower');
        
        var avTowerConf = gConfAvTower[rewardFloor];
        var awards =[];
        for( var i = 1; i < 10; i++) {
            var award = avTowerConf['Award'+i];
            if( !award ) {
                continue;    
            } 

            awards.push(award);
        }

        resp.data.awards = player.addAwards(awards);
    }while(false);

    onHandled();
}

exports.get_fight_force_reward = function(player, req, resp, onHandled){
    do {
        if( isNaN(req.args.fight_force) || !gConfAvFightForce[req.args.fight_force] ) {
            resp.code = 1; resp.desc = 'invalid args'; break;
        }
        
        var rewardFightForce = parseInt(req.args.fight_force);

        var activitySchedule = findActivitySchedule('fightforce');
        if( !activitySchedule ) {
            resp.code = 1; resp.desc = 'not open'; break;
        }

        var user = player.user;
        var activitiesConf = gConfActivities.fightforce;
        if( user.status.level < activitiesConf.OpenLevel ) {
            resp.code = 1; resp.desc = 'level not reach'; break;
        }

        player.getFightForce();
        if( user.status.fight_force < rewardFightForce ) {
            resp.code = 1; resp.desc = 'fight force not reach'; break;
        }

        var rewardGotFightForce = user.activity.fight_force;
        if( rewardFightForce <= rewardGotFightForce ) {
            resp.code = 1; resp.desc = 'have got'; break;
        }

        user.activity.fight_force = rewardFightForce;
        player.markDirty('activity.fight_force');
        
        var avFightForceConf = gConfAvFightForce[rewardFightForce];
        var awards =[];
        for( var i = 1; i < 10; i++) {
            var award = avFightForceConf['Award'+i];
            if( !award ) {
                continue;    
            } 

            awards.push(award);
        }

        resp.data.awards = player.addAwards(awards);
    }while(false);

    onHandled();
}

exports.get_player_level_reward = function(player, req, resp, onHandled){
    do {
        if( isNaN(req.args.level) || !gConfAvPlayerLevel[req.args.level] ) {
            resp.code = 1; resp.desc = 'invalid args'; break;
        }
        
        var rewardLevel = parseInt(req.args.level);
        var activitySchedule = findActivitySchedule('levelrank');
        if( !activitySchedule ) {
            resp.code = 1; resp.desc = 'not open'; break;
        }

        var user = player.user;
        var activitiesConf = gConfActivities.levelrank;
        if( user.status.level < activitiesConf.OpenLevel ) {
            resp.code = 1; resp.desc = 'level not reach open'; break;
        }

        if( user.status.level < rewardLevel ) {
            resp.code = 1; resp.desc = 'level not reach rank'; break;
        }

        var rewardGotLevel = user.activity.player_level;
        if( rewardLevel <= rewardGotLevel ) {
            resp.code = 1; resp.desc = 'have got'; break;
        }

        user.activity.player_level = rewardLevel;
        player.markDirty('activity.player_level');
        
        var awards = [];
        for( var i = 1; i < 10; i++) {
            var award = gConfAvPlayerLevel[rewardLevel]['Award' + i];
            if( !award ) {
                continue;    
            } 

            awards.push(award);
        } 

        resp.data.awards = player.addAwards(awards);

    }while(false);

    onHandled();
}

exports.buy_group_on = function(player, req, resp, onHandled){
    do {
        var exchangeId = req.args.id ? req.args.id : 0;

        var activitySchedule = findActivitySchedule('groupon');
        if( !activitySchedule ) {
            resp.code = 1; resp.desc = 'not open'; break;
        }

        var user = player.user;

        var groupOn = user.activity.group_on;
        if( !exchangeId && groupOn.buy >= gConfGlobal.GrouponDailyLimit ) {
            resp.code = 1; resp.desc = 'no buy'; break;
        }

        var passedDay = (new Date()).getDayPassed(activitySchedule.time);
        var avGroupOnConf = gConfAvGroupOn[passedDay];
        if( exchangeId && !(avGroupOnConf['Award_' + exchangeId] 
            && avGroupOnConf['Score' + exchangeId]) ) {
            resp.code = 1; resp.desc = 'invalid id'; break;
        }

        var awards = [];
        if( exchangeId ) {
            // 兑换物品
            if( !player.addInventory('material', gConfGlobal.GrouponScoreId, -avGroupOnConf['Score'+exchangeId]) ){
                resp.code = 1; resp.desc = 'not enough material'; break;
            }

            awards.push(avGroupOnConf['Award_' + exchangeId]);
        }else {
            // 购买物品 
            if( !player.costResource('cash', avGroupOnConf.Cash, groupOn.buy) ) {
                resp.code = 1; resp.desc = 'not enough cash'; break;
            }
            
            for( var i = 1; i < 10; i++) {
                var award = avGroupOnConf['Award' + i];
                if( !award ) {
                    continue; 
                }

                awards.push(award);
            }

            groupOn.buy += 1;
            player.markDirty('activity.group_on.buy'); 

            resp.data.cash = - avGroupOnConf.Cash;
        }

        resp.data.awards = player.addAwards(awards);
    }while(false);

    onHandled();
}

exports.get_western = function(player, req, resp, onHandled){
    do {
        var activitySchedule = findActivitySchedule('western');
        if( !activitySchedule ) {
            resp.code = 1; resp.desc = 'not open'; break;
        }

        var user = player.user;
        if( user.status.level < gConfActivities.western.OpenLevel ) {
            resp.code = 1; resp.desc = 'level not reach'; break;
        }

        if( user.activity.western.time != activitySchedule.time ) {
            user.activity.western = {
                'time':activitySchedule.time,
                'id':1,             
                'cards':[],      
                'opened':[],    
                'back':0,      
            };
            player.markDirty('activity.western');
        }

        resp.data.western = user.activity.western;
    }while(false);

    onHandled();
}

exports.go_western = function(player, req, resp, onHandled) {
    do {
        var costType = req.args.type ? req.args.type : 0;
        if( costType && !('cash' == costType || 'gold' == costType) ) {
            resp.code = 1; resp.desc = 'invalid args'; break;
        }

        var activitySchedule = findActivitySchedule('western');
        if( !activitySchedule ) {
            resp.code = 1; resp.desc = 'invalid time'; break;
        }
        
        var user = player.user;
        var western  = user.activity.western;
        if( !gConfAvWestern[western.id+1] || western.back >= gConfGlobal.WesternGobackLimit ) {
            resp.code = 1; resp.desc = 'no go back times'; break;
        }
        
        var passed = false;
        if( western.cards.indexOf(PassCardId) >= 0 ) {
            // 存在通关卡牌
            passed = true;
        }
        
        if( !passed && (western.id > 2) && (costType != 'cash') ) {
            // 在疏勒后的所有城市,在没有通关卡的情况下，必须使用元宝再来一次 
            resp.code = 1; resp.desc = 'invalid cost type'; break;
        }

        var newId = western.id;
        if( passed ) {
            if( costType ) {
                resp.code = 1; resp.desc = 'can not use resource'; break;
            }
            // 通关后,走到下一城市
            newId = western.id + 1;
        }

        // 已经走过,但是没有通关,并且不用Cash or Gold
        if( !passed && (western.cards.length > 0) && !costType) {
            resp.code = 1; resp.desc = 'not pass and no resource to go'; break;
        }

        var avwesternConf = gConfAvWestern[newId];
        var costNum=0;
        if( costType ) {
            costNum = +avwesternConf[costType.capWord()];
            if (!player.costResource('cash', costNum, western.id)) {
                resp.code = 1; resp.desc = 'not enough resource'; break;
            }
        }
        
        // 先找出所有卡本次选出对应的奖励 
        var cardRewards = [];
        for( var i=1; i<=8; i++ ) {
            cardRewards.push(common.randArray(avwesternConf['Reward'+i]));
        }

        var selectedCardNum = 5;
        if( gConfAvWestern[newId+1] && 
            common.randRange(1, 100) <= avwesternConf.CardPass ) {
            // 不是最后一关，并且通关,4个奖励卡牌
            selectedCardNum = 4;
        }

        var allCards = {};
        for( var i=1; i<=8; i++ ) {
            allCards[i] = avwesternConf['Card'+i];
        }

        var selectedCards = [];
        for( var i=1; i<=selectedCardNum; i++ ) {
            // 随机找到卡对应的奖励
            var card = common.wRand(allCards);
            selectedCards.push( cardRewards[card-1] );
            delete allCards[card];
        }
        
        if( selectedCardNum == 4 ) {
            // 把通关的卡牌Id随机插入翻牌结果中
            var index = common.randRange(0,3);
            selectedCards.splice(index, 0, PassCardId); 
        }
        
        western.id = newId;
        western.opened = [];
        western.cards = selectedCards;
        player.markDirty('activity.western');
        
        if( passed && avwesternConf.Award1 ) {
            // 到达特定关卡时额外奖励 
            resp.data.awards = player.addAwards([avwesternConf.Award1]);
        }

        resp.data.western = user.activity.western; 
        resp.data.cost = -costNum;
        resp.data.all_cards = cardRewards;

    }while(false);

    onHandled();
}

exports.open_western = function(player, req, resp, onHandled) {
    do {
        if( isNaN(req.args.pos) ) {
            resp.code = 1; resp.desc = 'no valid args'; break;
        }

        var pos = +req.args.pos;

        var user = player.user;
        var western  = user.activity.western;

        var cards = western.cards;
        var opened = western.opened;

        if( cards.length < 5 ) {
            resp.code = 1; resp.desc = 'not go here'; break;
        }

        if( opened.length >= cards.length ) {
            resp.code = 1; resp.desc = 'not more card to open'; break;
        }

        var avwesternConf = gConfAvWestern[western.id];

        var costNum = +avwesternConf.GoldOpen;
        if( !player.costResource('gold', costNum) ) {
            resp.code = 1; resp.desc = 'not enough gold'; break;
        }
        
        var award = cards[opened.length];
        if( award != PassCardId ) {
            player.addAwards([award]);
        }

        opened.push(pos);
        player.markDirty('activity.western.opened');

        resp.data.awards = [award];
        resp.data.cost = -costNum;

    }while(false);

    onHandled();
}

exports.back_western = function(player, req, resp, onHandled) {
    do {
        var western = player.user.activity.western;
        if( western.back >= gConfGlobal.WesternGobackLimit ) {
            resp.code = 1; resp.desc = 'no time'; break;
        }

        western.id = 1;
        western.cards = [];
        western.opened = [];
        western.back += 1;

        player.markDirty('activity.western');
        
    }while(false);

    onHandled();
}

exports.auto_open_western = function (player, req, resp, onHandled){
    do {
        var user = player.user;
        var western  = user.activity.western;

        var cards = western.cards;
        var opened = western.opened;
        if ( opened.length != 0 || cards.length != 5 ){
            resp.code = 1; resp.desc = 'invalid oop'; break;
        }
        
        var avwesternConf = gConfAvWestern[western.id];
        var costNum = avwesternConf.GoldOpen * 5;
        if( !player.costResource('gold', costNum) ) {
            resp.code = 1; resp.desc = 'not enough gold'; break;
        }
        
        var awards = [];
        for( var k=0, len = cards.length; k<len; k++ ) {
            if ( cards[k] != PassCardId ) {
                awards.push(cards[k]);
            }
        }   

        awards = player.addAwards(awards);
        
        var randNums= [1,2,3,4,5,6,7,8,9];
        var selectNums = [];
        for( var i=1; i<=5; i++ ) {
            var num =  common.randArray(randNums);  
            randNums.remove(num);
            selectNums.push(num);
        }

        western.opened = selectNums;
        player.markDirty('activity.western.opened');

        resp.data.cost = -costNum;
        resp.data.awards = awards;
        resp.data.opened = selectNums;

    }while (false);

    onHandled();
}

exports.visit_cottage = function (player, req, resp, onHandled){
    do {
        var user = player.user;
        if( user.status.level < gConfGlobal.VisitOpenLevel ) {
            resp.code = 1; resp.desc = 'level not reach'; break;
        }

        var visitCottage  = user.activity.visit_cottage;
        if( visitCottage.got ) {
            resp.code = 1; resp.desc = 'have got'; break;
        }

        if( visitCottage.cash ) {
            resp.code = 1; resp.desc = 'no free chance'; break;
        }

        if( visitCottage.free ) {
            resp.code = 1; resp.desc = 'have visit'; break;
        }

        if( visitCottage.count > 3 || visitCottage.visit >= 3 ) {
            resp.code = 1; resp.desc = 'no visit time'; break;
        }
        
        if( 0 == visitCottage.visit ) {
            visitCottage.count = 1; 
            player.markDirty('activity.visit_cottage.count');
        }

        visitCottage.free += 1;
        visitCottage.visit += 1;
        
        player.markDirty('activity.visit_cottage.free');
        player.markDirty('activity.visit_cottage.visit');
        
        // 送锦囊
        resp.data.awards = player.addAwards([['material', 86, 1]]);
    }while (false);

    onHandled();
}

exports.visit_cottage_enroll = function (player, req, resp, onHandled){
    do {
        
        var isCash = req.args.cash ? 1 : 0;
        
        var user = player.user;

        if( user.status.level < gConfGlobal.VisitOpenLevel ) {
            resp.code = 1; resp.desc = 'level not reach'; break;
        }

        var visitCottage  = user.activity.visit_cottage;
        if( visitCottage.got ) {
            resp.code = 1; resp.desc = 'have enroll'; break;
        }

        if( isCash ) {
            if( !visitCottage.cash ) {
                resp.code = 1; resp.desc = 'no cash enroll '; break;
            } 
            
            if( !player.costResource('cash', gConfGlobal.VisitEnrollCash) ) {
                resp.code = 1; resp.desc = 'not enough cash'; break;
            }
            
            resp.data.cash = -gConfGlobal.VisitEnrollCash;
        }else {
            if( visitCottage.count < 3 || visitCottage.visit != 3) {
                resp.code = 1; resp.desc = 'not enough login'; break;
            }        

        }
        
        visitCottage.got = 1;
        player.markDirty('activity.visit_cottage.got');
        // 送诸葛亮卡牌
        resp.data.awards = player.addAwards([['card', 13, 1]]);
    }while (false);

    onHandled();
}

exports.get_payrank = function (player, req, resp, onHandled){
    do {
        var activitySchedule = findActivitySchedule('payrank', 1);
        if( !activitySchedule ) {
            resp.code = 1; resp.desc = 'not open'; break;
        }

        var activity = player.user.activity;
        if( activity.pay_rank.time != activitySchedule.time ) {
            activity.pay_rank = {
                'time' : activitySchedule.time,
                'paid' : {},
                'got' : {},
            };
            player.markDirty('activity.pay_rank');
        }
        resp.data.pay_rank = activity.pay_rank;
    }while(false);
    onHandled();
}

exports.get_payrank_reward = function (player, req, resp, onHandled){
    do {
        if( isNaN(req.args.day) || isNaN(req.args.cash) ) {
            resp.code = 1; resp.desc = 'no valid args'; break;
        }

        var activitySchedule = findActivitySchedule('payrank', 1);
        if (!activitySchedule) {
            resp.code = 1; resp.desc = 'not open'; break;
        }

        var day = Math.round(req.args.day);
        var cash = Math.round(req.args.cash);

        var user = player.user;
        var pay_rank  = user.activity.pay_rank;
        
        var passedDay = common.getDayPassed(pay_rank.time);
        if( day >= passedDay ) {
            resp.code = 1; resp.desc = 'time not reach'; break;
        }

        if( pay_rank.got[day] ) {
            resp.code = 1; resp.desc = 'got'; break;
        }
        
        var paid = pay_rank.paid[day] || 0;
        if( paid < cash ) {
            resp.code = 1; resp.desc = 'not reach'; break;
        }
        
        var rewardConf = gConfAvPay[activitySchedule.conf][day];
        if( !rewardConf ) {
            resp.code = 1; resp.desc = 'invalid day'; break;
        }
        rewardConf = rewardConf[cash];
        if( !rewardConf ) {
            resp.code = 1; resp.desc = 'invalid reward cash'; break;
        }

        var awards = [rewardConf.Award1, rewardConf.Award2];
        awards = player.addAwards(awards);

        pay_rank.got[day] = 1;
        player.markDirty('activity.pay_rank.got');

        resp.data.awards = awards;

    }while (false);

    onHandled();
}

exports.get_payrank_top = function (player, req, resp, onHandled){
    do {
        var activitySchedule = findActivitySchedule('payrank', 1);
        if( !activitySchedule ) {
            resp.code = 1; resp.desc = 'time not reach'; break;
        }

        var pay_rank = player.user.activity.pay_rank;
        var totalPaid = 0;
        for( var day in pay_rank.paid ) {
            totalPaid += pay_rank.paid[day]; 
        }

        req.args.conf = activitySchedule.conf;
        req.args.paid = totalPaid;
        requestWorld(req, resp, function(){
            resp.data.paid = totalPaid;
            onHandled();
        });
        return;
    } while (false);

    onHandled();
}

exports.get_payrank_top10reward = function (player, req, resp, onHandled){
    do {
        var activitySchedule = findActivitySchedule('payrank', 2);
        if( !activitySchedule ) {
            resp.code = 1; resp.desc = 'time not reach'; break;
        }

        var user = player.user;
        var pay_rank = user.activity.pay_rank;

        if( pay_rank.top10_reward ) {
            resp.code = 1; resp.desc = 'got'; break;
        }

        req.args.conf = activitySchedule.conf;

        requestWorld(req, resp, function(){
            if( resp.code == 0 ) {
                pay_rank.top10_reward = 1;
                player.markDirty('activity.pay_rank.top10_reward');

                var rewardConf = gConfAvPayRank[activitySchedule.conf][resp.data.rank];
                var awards = [rewardConf.Award1, rewardConf.Award2, rewardConf.Award3, rewardConf.Award4];
                awards = player.addAwards(awards);

                resp.data.awards = awards;
            }
            onHandled();
        });
        return; 
    }while (false);

    onHandled();
}

exports.get_wealth = function(player, req, resp, onHandled){
    do {
        var activitySchedule = findActivitySchedule('wealth');
        if( !activitySchedule ) {
            resp.code = 1; resp.desc = 'not open'; break;
        }

        var activitiesConf = gConfActivities.wealth; 
        if( user.activity.wealth.time != activitiesConf.StartTime ) {
            user.activity.wealth = {
                'time':activitiesConf.StartTime,
                'count':0,
            };
            player.markDirty('activity.wealth');
        }
        
        resp.data.messages = gWealthMessages.get();
        resp.data.wealth = user.activity.wealth;
    }while(false);

    onHandled();
}

exports.get_wealth_reward = function(player, req, resp, onHandled){
    do {
        var user = player.user;
        var wealth = user.activity.wealth;
        var welcomeCount = wealth.count + 1;
        if( !gConfAvWealth[welcomeCount] ) {
            resp.code = 1; resp.desc = 'id error'; break;
        }

        var activitySchedule = findActivitySchedule('wealth');
        if( !activitySchedule ) {
            resp.code = 1; resp.desc = 'not open'; break;
        }

        var activitiesConf = gConfActivities.wealth;
        if( user.status.level < activitiesConf.OpenLevel ) {
            resp.code = 1; resp.desc = 'level not reach'; break;
        }
        
        var wealthConf = gConfAvWealth[welcomeCount];
        if( !player.costResource('cash', wealthConf.Cash, wealth.count) ) {
            resp.code = 1; resp.desc = 'not enougth cash'; break;
        }
        
        var earnCash = common.randRange(wealthConf.CashMin, wealthConf.CashMax);
        if( earnCash > 0 ) {
            // 赚取元宝
            player.alterResource('cash', earnCash);
        }

        wealth.count += 1;
        player.markDirty('activity.wealth.count');
        
        gWealthMessages.insert([ user.info.un, earnCash, (Math.round(earnCash / wealthConf.Cash * 10) / 10) ]);
        
        resp.data.cash = earnCash;
        resp.data.cost = -wealthConf.Cash;
        resp.data.messages = gWealthMessages.get();
    } while(false);

    onHandled();
}

exports.get_gem_buy = function(player, req, resp, onHandled) {
    var activitySchedule = findActivitySchedule('gembuy');
    if( !activitySchedule ) {
        resp.code = 1; resp.desc = 'not open';
        onHandled();
        return;
    }

    requestWorld(req, resp, function(){
        onHandled();
    });
}

exports.do_gem_buy = function(player, req, resp, onHandled) {
    var user = player.user;
    var id = parseInt(req.args.id);
    var gemBuyConf = null;
    var cashCost = 0;
    var confId = 0;
    do {
        var activitySchedule = findActivitySchedule('gembuy');
        if( !activitySchedule ) {
            resp.code = 1; resp.desc = 'not open'; break;
        }
        
        confId = activitySchedule.conf;
        if( !gConfAvGemBuy[confId] || !gConfAvGemBuy[confId][id] ) {
            resp.code = 1; resp.desc = 'invalid id'; break;
        }

        gemBuyConf = gConfAvGemBuy[confId][id];

        cashCost = gemBuyConf.Cash;
        if( cashCost > user.status.cash ) {
            resp.code = 1; resp.desc = 'no more cash'; break;
        }
    }while(false);

    if( resp.code != 0 ) {
        onHandled();
        return;
    }
    
    req.args.conf_id = confId;
    requestWorld(req, resp, function(){
        if( resp.code == 0 && !resp.data.over ) {
            player.costResource('cash', cashCost, id);
            var awards = [
                gemBuyConf.Award1, 
                gemBuyConf.Award2,
                gemBuyConf.Award3,
                gemBuyConf.Award4, 
                gemBuyConf.Award5,
            ];

            awards = awards.concat(gemBuyConf.Awards1);
            resp.data.awards = player.addAwards(awards);
            resp.data.cash = -cashCost;
        }
        onHandled();
    });
}

exports.hit_box = function (player, req, resp, onHandled){
    do {
        var user = player.user;
        if( user.status.level < gConfGlobal.HitBoxLevelLimit ) {
            resp.code = 1; resp.desc = 'level not reach'; break;
        }

        var hitBox  = user.activity.hit_box;
        if( hitBox.got ) {
            resp.code = 1; resp.desc = 'have got'; break;
        }

        if( hitBox.free ) {
            resp.code = 1; resp.desc = 'have hit'; break;
        }

        hitBox.hit += 1;
        hitBox.free += 1;
        
        player.markDirty('activity.hit_box');

        var weights = {};
        for( var i=1; i<=10; i++ ) {
            var award = gConfHitBoxReward.day['Award' + i];
            if( !award ) {
                continue;    
            } 
            weights[i] = gConfHitBoxReward.day['Weight'+i];
        }
            
        resp.data.hit_box = hitBox;
        resp.data.awards = player.addAwards([gConfHitBoxReward.day['Award'+common.wRand(weights)]]);
    }while (false);

    onHandled();
}

exports.get_hit_box_reward = function (player, req, resp, onHandled){
    do {
        
        var user = player.user;

        if( user.status.level < gConfGlobal.HitBoxLevelLimit ) {
            resp.code = 1; resp.desc = 'level not reach'; break;
        }

        var hitBox  = user.activity.hit_box;
        if( hitBox.got ) {
            resp.code = 1; resp.desc = 'have got'; break;
        }

        if( hitBox.hit < gConfGlobal.HitBoxTimes ) {
            resp.code = 1; resp.desc = 'not enough hit'; break;
        }
        
        hitBox.got = 1;
        player.markDirty('activity.hit_box.got');
        
        var awards = [];
        for( var i = 1; i < 10; i++) {
            var award = gConfHitBoxReward.all['Award' + i];
            if( !award ) {
                continue;    
            } 

            awards.push(award);
        } 

        resp.data.awards = player.addAwards(awards);

    }while (false);

    onHandled();
}

exports.get_charge_feed = function (player, req, resp, onHandled){
    do {
        var activitySchedule = findActivitySchedule('chargefeed');
        if( !activitySchedule ) {
            resp.code = 1; resp.desc = 'not open'; break;
        }

        var user = player.user;

        if( !user.activity.charge_feed || user.activity.charge_feed.time != activitySchedule.time ) {
            user.activity.charge_feed = {
                'score': 0,          
                'time': activitySchedule.time,
                'cost': 0,
                'exchange': 0,
                'got': {},
            };
            player.markDirty('activity.charge_feed');
        }

        resp.data.charge_feed = user.activity.charge_feed;
    }while (false);

    onHandled();
}

exports.open_charge_feed = function (player, req, resp, onHandled){
    do {
        var activitySchedule = findActivitySchedule('chargefeed');
        if( !activitySchedule ) {
            resp.code = 1; resp.desc = 'not open'; break;
        }

        var user = player.user;
        var chargeFeed = user.activity.charge_feed;
        if( chargeFeed.exchange < gConfGlobal.ChargeFeedExchangeCost) {
            resp.code = 1; resp.desc = 'not enough exchange'; break;
        }

        var chargeFeedConf = gConfAvChargeFeedSlot[activitySchedule.conf];
        var weights = {};
        for( var id in chargeFeedConf ) {
            weights[id] = chargeFeedConf[id].Weight;
        }

        var id = +common.wRand(weights);
        var awards = [chargeFeedConf[id].Award1];
        awards = player.addAwards(awards);

        chargeFeed.exchange -= gConfGlobal.ChargeFeedExchangeCost;
        player.markDirty('activity.charge_feed.exchange');

        resp.data.awards = awards;
        resp.data.award_id = id;
        resp.data.exchange = gConfGlobal.ChargeFeedExchangeCost;

    }while (false);

    onHandled();
}

exports.exchange_charge_feed = function (player, req, resp, onHandled){
    do {
        if( isNaN(req.args.id) ) {
            resp.code = 1; resp.desc = 'no valid args'; break;
        }

        var num = 1;
        if( !isNaN(req.args.num) ) {
            num = Math.round(req.args.num);
        }

        if( num <= 0 ) {
            resp.code = 1; resp.desc = 'invalid num'; break;
        }

        var activitySchedule = findActivitySchedule('chargefeed');
        if( !activitySchedule ) {
            resp.code = 1; resp.desc = 'not open'; break;
        }

        var id = +req.args.id;
        var chargeFeedConf = gConfAvChargeFeedScore[activitySchedule.conf][id];
        if( !chargeFeedConf ) {
            resp.code = 1; resp.desc = 'invalid id'; break;
        }
        
        var user = player.user;
        var chargeFeed = user.activity.charge_feed;
        if( ((chargeFeed.got[id] || 0 ) + num) > chargeFeedConf.MaxExchange ) {
            resp.code = 1; resp.desc = 'exchange up to max'; break;
        }
        
        if( (chargeFeedConf.Score * num + chargeFeed.cost) > chargeFeed.score ) {
            resp.code = 1; resp.desc = 'not enough score'; break;
        }

        var awards = [];
        for( var i=1; i<=num; i++ ) {
            awards.push(chargeFeedConf.Award1);
        }
        awards = player.addAwards(awards);
        
        chargeFeed.got[id] = (chargeFeed.got[id] || 0 ) + num;
        chargeFeed.exchange += num;
        chargeFeed.cost += chargeFeedConf.Score * num;
        player.markDirty('activity.charge_feed');

        resp.data.awards = awards;
        resp.data.score = chargeFeedConf.Score * num;

    }while (false);

    onHandled();
}

exports.get_cost_gift = function (player, req, resp, onHandled){
    do {
        var activitySchedule = findActivitySchedule('costgift');
        if( !activitySchedule ) {
            resp.code = 1; resp.desc = 'not open'; break;
        }

        var user = player.user;
        if( !user.activity.cost_gift || user.activity.cost_gift.time != activitySchedule.time ) {
            user.activity.cost_gift = {
                'cash': 0,          
                'time': activitySchedule.time,
                'got': {},
                'extra_got': {},
            };
            player.markDirty('activity.cost_gift');
        }

        resp.data.cost_gift = user.activity.cost_gift;
    }while (false);

    onHandled();
}

exports.cost_gift_reward = function (player, req, resp, onHandled) {
    do {
        if( isNaN(req.args.cash) ) {
            resp.code = 1; resp.desc = 'no valid args'; break;
        }

        var cash = +req.args.cash;

        var activitySchedule = findActivitySchedule('costgift');
        if( !activitySchedule ) {
            resp.code = 1; resp.desc = 'not open'; break;
        }
        var costGiftConf = gConfAvCostGift[activitySchedule.conf][cash];
        if( !costGiftConf ) {
            resp.code = 1; resp.desc = 'invalid id'; break;
        }

        var user = player.user;
        var costGift = user.activity.cost_gift;

        if( costGift.got[cash] ) {
            resp.code = 1; resp.desc = 'got'; break;
        }

        if( costGift.cash < cash ) {
            resp.code = 1; resp.desc = 'not reach'; break;
        }

        var awards = [costGiftConf.Award1, costGiftConf.Award2, costGiftConf.Award3, costGiftConf.Award4];
        awards = player.addAwards(awards);

        costGift.got[cash] = 1;
        player.markDirty('activity.cost_gift.got');

        resp.data.awards = awards;
    }while (false);

    onHandled();
}

exports.cost_gift_extra_reward = function (player, req, resp, onHandled) {
    do {
        if( isNaN(req.args.cash) ) {
            resp.code = 1; resp.desc = 'no valid args'; break;
        }

        var cash = +req.args.cash;

        var activitySchedule = findActivitySchedule('costgift');
        if( !activitySchedule ) {
            resp.code = 1; resp.desc = 'not open'; break;
        }

        var costGiftConf = gConfAvCostGift[activitySchedule.conf][cash];
        if( !costGiftConf ) {
            resp.code = 1; resp.desc = 'invalid id'; break;
        }

        var user = player.user;
        var costGift = user.activity.cost_gift;

        // 判断蓝钻
        if( user.info.blue <= 0 ) {
            resp.code = 1; resp.desc = 'not blue'; break;
        }

        if( costGift.extra_got[cash] ) {
            resp.code = 1; resp.desc = 'got'; break;
        }

        if( costGift.cash < cash ) {
            resp.code = 1; resp.desc = 'not reach'; break;
        }

        var awards = [costGiftConf.Award5];
        awards = player.addAwards(awards);

        costGift.extra_got[cash] = 1;
        player.markDirty('activity.cost_gift.extra_got');

        resp.data.awards = awards;
    }while (false);

    onHandled();
}

exports.thanks_back_get = function(player, req, resp, onHandled){
    do {
        var activity = player.getActivity('thanksback', {alias:true});
        if (!activity) {
            resp.code = 1; resp.desc = 'not open'; break;
        }

        resp.data.thanks_back = activity;
    }while (false);

    onHandled();
}

exports.thanks_back_reward = function (player, req, resp, onHandled) {
    do {
        if (isNaN(req.args.id)) {
            resp.code = 1; resp.desc = 'no valid args'; break;
        }

        var id = +req.args.id;
    
        var user = player.user;
        var activityKey = 'thanksback';
        var activityInfo = player.getActivity(activityKey, {alias:true, conf:true});
        if (!activityInfo || !activityInfo.data) {
            resp.code = 1; resp.desc = 'activity not open'; break;
        }

        var activity = activityInfo.data;
        var thanksBackConf = gConfAvThanksBack[activityInfo.conf.conf][id];
        if (!thanksBackConf) {
            resp.code = 1; resp.desc = 'invalid id'; break;
        }

        if (activity.got[id]) {
            resp.code = 1; resp.desc = 'got'; break;
        }

        if (activity.cash < thanksBackConf.Cash) {
            resp.code = 1; resp.desc = 'not reach'; break;
        }

        var awards = [thanksBackConf.Award1];
        awards = player.addAwards(awards);

        activity.got[id] = 1;
        player.saveActivityValue(activityKey, 'got', {alias:true});

        resp.data.awards = awards;
    }while (false);

    onHandled();
}

exports.get_new_charge = function(player, req, resp, onHandled) {
    do {
        var activitySchedule = findActivitySchedule('newcharge');
        if( !activitySchedule ) {
            resp.code = 1; resp.desc = 'not open'; break;
        }

        var user = player.user;

        if( user.activity.new_charge.time != activitySchedule.time ) {
            user.activity.new_charge = {
                'cash':0,          
                'time': activitySchedule.time,
                'got' : {
                }, 
            };
            player.markDirty('activity.new_charge');
        }

        resp.data.new_charge = user.activity.new_charge;
    }while(false);

    onHandled();
}

exports.new_charge_reward = function(player, req, resp, onHandled){
    do {
        if( isNaN(req.args.id) ) {
            resp.code = 1; resp.desc = 'invalid args'; break;
        }
        
        var rewardCashId = parseInt(req.args.id);
        var activitySchedule = findActivitySchedule('newcharge');
        if( !activitySchedule ) {
            resp.code = 1; resp.desc = 'not open'; break;
        }

        if( !gConfAvNewCharge[activitySchedule.conf][rewardCashId] ) {
            resp.code = 1; resp.desc = 'id error'; break;
        }

        var user = player.user;
        
        var new_charge = user.activity.new_charge;
        var new_chargedCash = +new_charge.cash;
        if( new_chargedCash < rewardCashId  ) {
            resp.code = 1; resp.desc = 'not enough cash'; break;
        }
        
        var got = new_charge.got;
        if( !(rewardCashId in got) ) {
            got[rewardCashId] = 0; 
        }        
        
        var canGotTime = 1;
        var avChargeConf = gConfAvNewCharge[activitySchedule.conf][rewardCashId];
        if( avChargeConf.IsRepeat ) {
            canGotTime = parseInt(new_chargedCash / rewardCashId); 
        }

        if( got[rewardCashId] >= canGotTime ) {
            resp.code = 1; resp.desc = 'have got'; break;
        } 

        got[rewardCashId] += 1;
        player.markDirty(util.format('activity.new_charge.got.%d', rewardCashId));

        var awards =[];
        for( var i = 1; i < 100; i++) {
            var award = avChargeConf['Award'+i];
            if( !award ) {
                continue;    
            } 

            awards.push(award);
        }

        awards = player.addAwards(awards);
        
        resp.data.awards = awards;
    }while(false);

    onHandled();
}

exports.get_my_limit = function (player, req, resp, onHandled) {
    do {
        var activitySchedule = findActivitySchedule('mylimit');
        if( !activitySchedule ) {
            resp.code = 1; resp.desc = 'not open'; break;
        }

        var myLimit = player.user.activity.my_limit;
        if( !myLimit || (activitySchedule.time != myLimit.time) ) {
            player.user.activity.my_limit = {
                'time' : activitySchedule.time,
                'buy' : {},
            };

            player.markDirty('activity.my_limit');
        }
        
        resp.data.my_limit = player.user.activity.my_limit;
    }while (false);

    onHandled();
}

exports.my_limit_buy = function (player, req, resp, onHandled) {
    do {
        var activitySchedule = findActivitySchedule('mylimit');
        if( !activitySchedule ) {
            resp.code = 1; resp.desc = 'not open'; break;
        }

        var myLimitConf = gConfAvMyLimit[activitySchedule.conf][req.args.id];
        if( !myLimitConf ) {
            resp.code = 1; resp.desc = 'invalid id'; break;
        }
        var id = req.args.id;
        var num = 1;
        if( !isNaN(req.args.num) ) {
            num = Math.round(req.args.num);
        }
        if( num <= 0 ) {
            resp.code = 1; resp.desc = 'invalid num'; break;
        }

        var user = player.user;
        var myLimit = user.activity.my_limit;
        if( ((myLimit.buy[id] || 0 ) + num) > myLimitConf.Total ) {
            resp.code = 1; resp.desc = 'buy max'; break;
        }

        if( !player.costResource('cash', myLimitConf.Cash * num, id, num) ) {
            resp.code = 1; resp.desc = 'not enough cash'; break;
        }

        myLimit.buy[id] = (myLimit.buy[id] || 0) + num;
        player.markDirty('activity.my_limit');

        var awards = [];
        for( var i=1; i<=num; i++ ) {
            awards.push(myLimitConf.Award1);
        }

        resp.data.cash = -myLimitConf.Cash * num;
        resp.data.awards = player.addAwards(awards);
    }while (false);

    onHandled();
}

exports.get_daily_payrank = function (player, req, resp, onHandled){
    do {
        var activitySchedule = findActivitySchedule('dailypayrank', 1);
        if( !activitySchedule ) {
            resp.code = 1; resp.desc = 'not open'; break;
        }

        if( !gConfAvDailyPayRank[activitySchedule.conf][req.args.day] ) {
            resp.code = 1; resp.desc = 'invalid day'; break;
        }

        var activity = player.user.activity;
        if( activity.daily_pay_rank.time != activitySchedule.time ) {
            activity.daily_pay_rank = {
                'time' : activitySchedule.time,
                'paid' : {},
            };
            player.markDirty('activity.daily_pay_rank');
        }
    }while(false);

    if( resp.code != 0 ) {
        onHandled();
        return;
    }

    requestWorld(req, resp, function(){
        resp.data.paid = player.user.activity.daily_pay_rank.paid[req.args.day] || 0;
        onHandled();
    });
}

exports.get_daily_payrank_top10reward = function (player, req, resp, onHandled){
    do {
        var activitySchedule = findActivitySchedule('dailypayrank', 1);
        if( !activitySchedule ) {
            resp.code = 1; resp.desc = 'time not reach'; break;
        }

        var day = common.getDayPassed(activitySchedule.time);
        var avDayConf = gConfAvDailyPayRank[activitySchedule.conf][req.args.day];

        if (!avDayConf) {
            resp.code = 1; resp.desc = 'invalid day'; break;
        }

        if( +req.args.day >= day ) {
            resp.code = 1; resp.desc = 'reward not reach'; break;
        }

        requestWorld(req, resp, function(){
            if( resp.code == 0 ) {
                var rewardConf = avDayConf[resp.data.rank];
                var awards = [rewardConf.Award1, rewardConf.Award2, rewardConf.Award3, rewardConf.Award4];
                awards = player.addAwards(awards);

                resp.data.awards = awards;
            }
            onHandled();
        });
        return; 
    }while (false);

    onHandled();
}

exports.buy_role_send = function (player, req, resp, onHandled){
    do {
        var activitySchedule = findActivitySchedule('rolesend');
        if( !activitySchedule ) {
            resp.code = 1; resp.desc = 'time not reach'; break;
        }

        if( isNaN(req.args.id) ) {
            resp.code = 1; resp.desc = 'invalid args'; break;
        }        

        var roleId = req.args.id;
        var roleSendConf = gConfAvRoleSend[activitySchedule.conf];
        if( !roleSendConf[roleId] ) {
            resp.code = 1; resp.desc = 'invalid id'; break;
        }
        
        var costCash = roleSendConf[roleId].Cash;
        if( !player.costResource('cash', costCash, roleId) ) {
            resp.code = 1; resp.desc = 'not enough cash'; break;
        }

        resp.data.awards = player.addAwards([roleSendConf[roleId].Award1]);
        resp.data.cash = -costCash;

    }while (false);

    onHandled();
}

exports.get_pet_gift = function (player, req, resp, onHandled){
    do {
        var activitySchedule = findActivitySchedule('petgift');
        if( !activitySchedule ) {
            resp.code = 1; resp.desc = 'time not reach'; break;
        }

        var petGift = player.user.activity.pet_gift;
        if( !petGift || (petGift.time != activitySchedule.time) ) {
            player.user.activity.pet_gift = {
                'time': activitySchedule.time,
                'got': {},
            };
            player.markDirty('activity.pet_gift');
        }

        resp.data.pet_gift = player.user.activity.pet_gift;
    }while (false);

    onHandled();
}

exports.pet_gift_reward = function (player, req, resp, onHandled){
    do {
        var activitySchedule = findActivitySchedule('petgift');
        if( !activitySchedule ) {
            resp.code = 1; resp.desc = 'time not reach'; break;
        }

        var petGiftConf = gConfAvPetGift[activitySchedule.conf][req.args.level];
        if( !petGiftConf ) {
            resp.code = 1; resp.desc = 'invalid level'; break;
        }

        var maxConfLevel = 0;
        for( var levelId in gConfAvPetGift[activitySchedule.conf] ) {
            if( +levelId > maxConfLevel ) {
                maxConfLevel = +levelId; 
            } 
        }
       
        var level = req.args.level;
        var petGift = player.user.activity.pet_gift;
        // 当神兽等级大于活动神兽最高等级，领取活动最高等级奖励
        if( petGift.got[level] || petGift.got[maxConfLevel] ) {
            resp.code = 1; resp.desc = 'have got'; break;
        }
    
        var petLevel = player.user.pet.level;
        if( level != petLevel && petLevel <= maxConfLevel) {
            resp.code = 1; resp.desc = 'level not reach'; break;
        }
        
        if( petLevel > maxConfLevel ) {
            petGift.got[maxConfLevel] = 1; 
        }else {
            petGift.got[level] = 1;
        }

        player.markDirty('activity.pet_gift');

        resp.data.awards = player.addAwards([petGiftConf.Award1, petGiftConf.Award2]);
    }while (false);

    onHandled();
}

exports.break_egg = function (player, req, resp, onHandled) {
    do {
        var activitySchedule = findActivitySchedule('breakegg');
        if( !activitySchedule ) {
            resp.code = 1; resp.desc = 'not open'; break;
        }

        if( [1,2,3].indexOf(req.args.pos) < 0 ) {
            resp.code = 1; resp.desc = 'invalid pos'; break;
        }

        var pos = req.args.pos;

        var user = player.user;
        var breakEgg = user.activity.break_egg;
        if( common.getTime() < breakEgg.timer ) {
            resp.code = 1; resp.desc = 'colding'; break;
        }else if( breakEgg.got > 0 ) {
            //不能重新砸 
            resp.code = 1; resp.desc = 'have reward'; break;
        }

        if( breakEgg.free >= gConfGlobal.BreakEggDailyLimit ) {
            resp.code = 1; resp.desc = 'no free'; break;
        }

        var reward = {};
        var weights = {};
        for( var i=1; i<=10; i++ ) {
            weights[i] = gConfAvBreakEgg[activitySchedule.conf].yes["Weight"+i];
        }
        reward[pos] = +common.wRand(weights);

        weights = {};
        for( var i=1; i<=10; i++ ) {
            weights[i] = gConfAvBreakEgg[activitySchedule.conf].no["Weight"+i];
        }

        for( var i=1; i<=3; i++ ) {
            if( i == pos ) continue;

            reward[i] = +common.wRand(weights);
            delete weights[reward[i]];
        }
        
        breakEgg.free += 1;
        breakEgg.reward = reward;
        breakEgg.got = pos;
        player.markDirty('activity.break_egg');

        resp.data.break_egg = breakEgg;

    }while (false);

    onHandled();
}

exports.break_egg_reward = function (player, req, resp, onHandled) {
    do {
        var activitySchedule = findActivitySchedule('breakegg');
        if( !activitySchedule ) {
            resp.code = 1; resp.desc = 'not open'; break;
        }

        var user = player.user;
        var breakEgg = user.activity.break_egg;
        if( breakEgg.got <= 0 ) {
            resp.code = 1; resp.desc = 'no reward'; break;
        }

        var awards = [gConfAvBreakEgg[activitySchedule.conf].yes["Award"+breakEgg.reward[breakEgg.got]]];

        breakEgg.got = -breakEgg.got;
        breakEgg.reward = {};
        breakEgg.timer = common.getTime() + gConfGlobal.BreakEggColdTime;

        player.markDirty('activity.break_egg');
        resp.data.awards = player.addAwards(awards);
    }while (false);

    onHandled();
}

exports.break_egg_clear = function (player, req, resp, onHandled) {
    do {
        var activitySchedule = findActivitySchedule('breakegg');
        if( !activitySchedule ) {
            resp.code = 1; resp.desc = 'not open'; break;
        }

        var user = player.user;
        var breakEgg = user.activity.break_egg;
        
        var cashCost = gConfGlobal.BreakEggClearCashCost;
        if( !player.costResource('cash', cashCost) ) {
            resp.code = 1; resp.desc = 'not enough cash'; break;
        }

        breakEgg.timer = 0;
        player.markDirty('activity.break_egg.timer');

        resp.data.cash = -cashCost;
    }while (false);

    onHandled();
}

exports.get_charge_role = function(player, req, resp, onHandled){
    do {
        var activitySchedule = findActivitySchedule('chargerole');
        if( !activitySchedule ) {
            resp.code = 1; resp.desc = 'not open'; break;
        }

        var user = player.user;

        if( user.activity.charge_role.time != activitySchedule.time ) {
            user.activity.charge_role = {
                'cash':0,          
                'time': activitySchedule.time,
                'got' : {
                }, 
            };
            player.markDirty('activity.charge_role');
        }

        resp.data.charge_role = user.activity.charge_role;
    }while(false);

    onHandled();
}

exports.charge_role_reward = function(player, req, resp, onHandled){
    do {
        if( isNaN(req.args.cash) ) {
            resp.code = 1; resp.desc = 'invalid args'; break;
        }

        var cash = +req.args.cash;
        
        var activitySchedule = findActivitySchedule('chargerole');
        if( !activitySchedule ) {
            resp.code = 1; resp.desc = 'not open'; break;
        }
        
        var chargeRoleConf = gConfAvChargeRole[cash];
        if( !chargeRoleConf ) {
            resp.code = 1; resp.desc = 'id error'; break;
        }

        var user = player.user;
        
        var chargeRole = user.activity.charge_role;
        if( chargeRole.got[cash] ) {
            resp.code = 1; resp.desc = 'got'; break;
        }
        
        if( chargeRole.cash < cash ) {
            resp.code = 1; resp.desc = 'not enough cash'; break;
        }

        chargeRole.got[cash] = 1;
        
        player.markDirty('activity.charge_role');

        resp.data.awards = player.addAwards([chargeRoleConf.Award1]);
    }while(false);

    onHandled();
}

exports.get_charge_limit = function(player, req, resp, onHandled){
    do {
        var activitySchedule = findActivitySchedule('chargelimit');
        if( !activitySchedule ) {
            resp.code = 1; resp.desc = 'not open'; break;
        }

        var user = player.user;

        if( user.activity.charge_limit.time != activitySchedule.time ) {
            user.activity.charge_limit = {
                'cash':0,          
                'time': activitySchedule.time,
                'got' : {
                }, 
                'buy' : {
                },
            };
            player.markDirty('activity.charge_limit');
        }

        resp.data.charge_limit = user.activity.charge_limit;
    }while(false);

    onHandled();
}

exports.charge_limit_reward = function(player, req, resp, onHandled){
    do {
        if( isNaN(req.args.cash) ) {
            resp.code = 1; resp.desc = 'invalid args'; break;
        }

        var cash = +req.args.cash;
        
        var activitySchedule = findActivitySchedule('chargelimit');
        if( !activitySchedule ) {
            resp.code = 1; resp.desc = 'not open'; break;
        }
        
        var chargeLimitConf = gConfAvChargeLimit[activitySchedule.conf][cash];
        if( !chargeLimitConf ) {
            resp.code = 1; resp.desc = 'cash error'; break;
        }

        var user = player.user;
        
        var chargeLimit = user.activity.charge_limit;
        if( chargeLimit.cash < cash ) {
            resp.code = 1; resp.desc = 'cash not reach'; break;
        }

        var got = chargeLimit.got[cash] || 0;
        if( chargeLimitConf.IsRepeat ) {
            if( got >= Math.floor(chargeLimit.cash/cash) ) {
                resp.code = 1; resp.desc = 'got'; break;
            }
        }else {
            if( got ) {
                resp.code = 1; resp.desc = 'got'; break;
            }
        }
        
        chargeLimit.got[cash] = got + 1;
        
        player.markDirty('activity.charge_limit.got');

        resp.data.awards = player.addAwards(chargeLimitConf.Awards1);
    }while(false);

    onHandled();
}

exports.charge_limit_buy = function(player, req, resp, onHandled) {
    do {
        if( isNaN(req.args.cash) || isNaN(req.args.id) ) {
            resp.code = 1; resp.desc = 'invalid args'; break;
        }
        
        var cash = +req.args.cash;
        var id = +req.args.id;
        var num = isNaN(req.args.num) ? 1 : Math.round(req.args.num);

        if( num < 1 ) {
            resp.code = 1; resp.desc = 'invalid num'; break;
        }
        
        var activitySchedule = findActivitySchedule('chargelimit');
        if( !activitySchedule ) {
            resp.code = 1; resp.desc = 'not open'; break;
        }
        
        var chargeLimitConf = gConfAvChargeLimit[activitySchedule.conf][cash];
        if( !chargeLimitConf ) {
            resp.code = 1; resp.desc = 'cash error'; break;
        }

        if( !chargeLimitConf['Award'+id] ) {
            resp.code = 1; resp.desc = 'id error'; break;
        }

        var user = player.user;
        
        var chargeLimit = user.activity.charge_limit;
        if( chargeLimit.cash < cash ) {
            resp.code = 1; resp.desc = 'cash not reach'; break;
        }

        if( !chargeLimit.buy[cash] ) {
            chargeLimit.buy[cash] = {};
        }

        var buy = chargeLimit.buy[cash][id] || 0;

        if( (buy+num) > chargeLimitConf['Num'+id] ) {
            resp.code = 1; resp.desc = 'no left'; break;
        }
        
        var cashCost = chargeLimitConf['Cash'+id] * num;
        if( !player.costResource('cash', cashCost, id, num) ) {
            resp.code = 1; resp.desc = 'not enough cash'; break;
        }
        
        chargeLimit.buy[cash][id] = buy + num;
        player.markDirty('activity.charge_limit.buy');

        var awards = [];
        for( var i=1; i<=num; i++ ) {
            awards.push(chargeLimitConf['Award'+id]);
        }

        resp.data.awards = player.addAwards(awards);
        resp.data.cash = -cashCost;
    }while(false);

    onHandled();
}

exports.get_chargegod_limit = function(player, req, resp, onHandled){
    do {
        var activitySchedule = findActivitySchedule('chargegod');
        if( !activitySchedule ) {
            resp.code = 1; resp.desc = 'not open'; break;
        }

        var user = player.user;

        if( user.activity.chargegod_limit.time != activitySchedule.time ) {
            user.activity.chargegod_limit = {
                'cash':0,          
                'time': activitySchedule.time,
                'got' : {
                }, 
                'buy' : {
                },
            };
            player.markDirty('activity.chargegod_limit');
        }

        resp.data.chargegod_limit = user.activity.chargegod_limit;
    }while(false);

    onHandled();
}

exports.chargegod_limit_reward = function(player, req, resp, onHandled){
    do {
        if( isNaN(req.args.cash) ) {
            resp.code = 1; resp.desc = 'invalid args'; break;
        }

        var cash = +req.args.cash;
        
        var activitySchedule = findActivitySchedule('chargegod');
        if( !activitySchedule ) {
            resp.code = 1; resp.desc = 'not open'; break;
        }
        
        var chargeGodRewardConf = gConfAvChargeGodReward[activitySchedule.conf][cash];
        if( !chargeGodRewardConf ) {
            resp.code = 1; resp.desc = 'cash error'; break;
        }

        var user = player.user;
        
        var chargeGodLimit = user.activity.chargegod_limit;
        if( chargeGodLimit.cash < cash ) {
            resp.code = 1; resp.desc = 'cash not reach'; break;
        }

        if( chargeGodLimit.got[cash] ) {
            resp.code = 1; resp.desc = 'got'; break;
        }
        
        chargeGodLimit.got[cash] = 1;
        
        player.markDirty('activity.chargegod_limit.got');

        resp.data.awards = player.addAwards([chargeGodRewardConf.Award1]);
    }while(false);

    onHandled();
}

exports.chargegod_limit_buy = function(player, req, resp, onHandled) {
    do {
        if( isNaN(req.args.cash) || isNaN(req.args.id) ) {
            resp.code = 1; resp.desc = 'invalid args'; break;
        }
        
        var cash = +req.args.cash;
        var num = isNaN(req.args.num) ? 1 : Math.round(req.args.num);

        if( num < 1 ) {
            resp.code = 1; resp.desc = 'invalid num'; break;
        }
        
        var activitySchedule = findActivitySchedule('chargegod');
        if( !activitySchedule ) {
            resp.code = 1; resp.desc = 'not open'; break;
        }
        
        var chargeGodLimitConf = gConfAvChargeGodLimit[activitySchedule.conf][cash];
        if( !chargeGodLimitConf ) {
            resp.code = 1; resp.desc = 'cash error'; break;
        }

        var user = player.user;
        
        var chargeGodLimit = user.activity.chargegod_limit;
        var buy = chargeGodLimit.buy[cash] || 0;

        if( (buy+num) > chargeGodLimitConf.Limit ) {
            resp.code = 1; resp.desc = 'no left'; break;
        }
        
        var cashCost = cash * num;
        if( !player.costResource('cash', cashCost, cash, num) ) {
            resp.code = 1; resp.desc = 'not enough cash'; break;
        }
        
        chargeGodLimit.buy[cash] = buy + num;
        player.markDirty('activity.chargegod_limit.buy');

        var awards = [];
        for( var i=1; i<=num; i++ ) {
            awards.push(chargeGodLimitConf.Award1);
            awards.push(chargeGodLimitConf.Award2);
        }

        resp.data.awards = player.addAwards(awards);
        resp.data.cash = -cashCost;
    }while(false);

    onHandled();
}

exports.exchange_cdkey = function(player, req, resp, onHandled) {
    do {
        resp.code = 1; resp.desc = 'not open'; break;
        if( !common.verifyGatewayAuth(util.format('%s%s%s', req.args.reward, req.args.id, req.uid), req.args.key) ) {
            resp.code = 1; resp.desc = 'invalid args'; break;
        }

        var id = req.args.id;
        if( isNaN(id) || Math.round(id) <= 0 || Math.round(id) > 999 ) {
            resp.code = 1; resp.desc = 'invalid cdkey id'; break;
        }

        var awards = [];
        try{
            awards = JSON.parse(req.args.reward);
        }catch(e){
            resp.code = 1; resp.desc = 'invalid reward'; break;
        }

        
        var cdkey = player.user.activity.cdkey;
        if( cdkey[id] ) {
            resp.code = 1; resp.desc = 'got'; break;
        }

        cdkey[id] = 1;
        player.markDirty('activity.cdkey');

        resp.data.awards = player.addAwards(awards);
    }while(false);

    onHandled();
}

/*
exports.get_star_gift = function(player, req, resp, onHandled){
    do {
        var activitySchedule = findActivitySchedule('stargift');
        if( !activitySchedule ) {
            resp.code = 1; resp.desc = 'not open'; break;
        }

        var user = player.user;

        if( user.activity.star_gift.time != activitySchedule.time ) {
            user.activity.star_gift = {
                'time': activitySchedule.time,
                'got' : {
                }, 
            };
            player.markDirty('activity.star_gift');
        }

        resp.data.star_gift = user.activity.star_gift;
    }while(false);

    onHandled();
}
*/

exports.star_gift_reward = function(player, req, resp, onHandled){
    do {
        if( isNaN(req.args.id) ) {
            resp.code = 1; resp.desc = 'invalid args'; break;
        }

        var id = req.args.id;
        
        var activitySchedule = findActivitySchedule('stargift');
        if( !activitySchedule ) {
            resp.code = 1; resp.desc = 'not open'; break;
        }
        
        var starGiftConf = gConfAvStarGift[id];
        if( !starGiftConf ) {
            resp.code = 1; resp.desc = 'id error'; break;
        }

        var user = player.user;
        
        var starGift = user.activity.star_gift;
        if( starGift.got[id] ) {
            resp.code = 1; resp.desc = 'got'; break;
        }

        // 判断需求
        var need1 = 0;
        var need2 = 0;
        
        var equips = user.equip;
        for( var eid in equips ) {
            var equip = equips[eid];
            var star = equip.star || 0;
            if( star >= starGiftConf.StarNum1 ) {
                need1 += 1;
            }
            if( star >= starGiftConf.StarNum2 ) {
                need2 += 1;
            }
        }

        if( need1 < starGiftConf.EquipNum1 && need2 < starGiftConf.EquipNum2 ) {
            resp.code = 1; resp.desc = 'star not reach'; break;
        }
        
        starGift.got[id] = 1;
        player.markDirty('activity.star_gift.got');

        resp.data.awards = player.addAwards([starGiftConf.Award1, starGiftConf.Award2]);
    }while(false);

    onHandled();
}

exports.diamond_card_start = function(player, req, resp, onHandled){
    do {
        var activitySchedule = findActivitySchedule('diamondcard');
        if( !activitySchedule ) {
            resp.code = 1; resp.desc = 'not open'; break;
        }

        var user = player.user;
        var diamondCard = user.activity.diamond_card;
        if( diamondCard.cards.length > 0 ) {
            resp.code = 1; resp.desc = 'not end'; break;
        }

        var cards = [];
        for( var pos in gConfAvDiamondCard ) {
            cards.push(common.wRand(gConfAvDiamondCard[pos].Item));
        }

        diamondCard.open = {};
        diamondCard.cards = cards;

        player.markDirty('activity.diamond_card');
        resp.data.cards = cards;
    }while(false);

    onHandled();
}

exports.diamond_card_refresh = function(player, req, resp, onHandled){
    do {
        var activitySchedule = findActivitySchedule('diamondcard');
        if( !activitySchedule ) {
            resp.code = 1; resp.desc = 'not open'; break;
        }

        var useCash = req.args.cash ? true : false;
        var cashCost = 0;

        var user = player.user;
        var diamondCard = user.activity.diamond_card;

        if( !useCash ) {
            if( diamondCard.free >= gConfGlobal.DiamondCardDailyLimit ) {
                resp.code = 1; resp.desc = 'no free'; break;
            }
        }else{
            if( !gConfAvDiamondCardCost[diamondCard.cash + 1] ) {
                resp.code = 1; resp.desc = 'no more times'; break;
            }

            cashCost = gConfAvDiamondCardCost[diamondCard.cash+1].RefreshCash;
            if( !player.costResource('cash', cashCost, diamondCard.cash) ) {
                resp.code = 1; resp.desc = 'not enough cash'; break;
            }
        }

        var cards = [];
        for( var pos in gConfAvDiamondCard ) {
            cards.push(common.wRand(gConfAvDiamondCard[pos].Item));
        }

        diamondCard.open = {};
        diamondCard.cards = cards;

        if( useCash ) {
            diamondCard.cash += 1;
        }else{
            diamondCard.free += 1;
        }
        
        player.markDirty('activity.diamond_card');
        resp.data.cards = cards;
        resp.data.cash = -cashCost;
    }while(false);

    onHandled();
}

exports.diamond_card_open = function(player, req, resp, onHandled){
    do {
        var activitySchedule = findActivitySchedule('diamondcard');
        if( !activitySchedule ) {
            resp.code = 1; resp.desc = 'not open'; break;
        }
        
        if( isNaN(req.args.pos) ) {
            resp.code = 1; resp.desc = 'invalid args'; break;
        }

        var pos = +req.args.pos;
        if( !gConfAvDiamondCard[pos] ) {
            resp.code = 1; resp.desc = 'invalid pos'; break;
        }
        
        var user = player.user;
        var diamondCard = user.activity.diamond_card;
        if( diamondCard.cards.length <= 0 ) {
            resp.code = 1; resp.desc = 'please refresh'; break;
        }

        if( pos in diamondCard.open ) {
            resp.code = 1; resp.desc = 'opend'; break;
        }

        var opened = Object.keys(diamondCard.open).length;
        if( opened >= diamondCard.cards.length ) {
            resp.code = 1; resp.desc = 'no more open'; break;
        }

        var cashCost = gConfAvDiamondCardCost[opened+1].OpenCash;
        if( !cashCost ) {
            resp.code = 1; resp.desc = 'no more open'; break;
        }

        if( !player.costResource('cash', cashCost, opened) ) {
            resp.code = 1; resp.desc = 'not enough cash'; break;
        }

        var weights = {};
        for( var id in gConfAvDiamondCard ) {
            weights[id-1] = gConfAvDiamondCard[id].Weight;
        }

        for( var poss in diamondCard.open ) {
            delete weights[diamondCard.open[poss]];
        }

        var index = +common.wRand(weights);
        diamondCard.open[pos] = index;
        player.markDirty('activity.diamond_card.open');
         
        var item = gConfAvDiamondCardItem[diamondCard.cards[index]];
        if( item.SendMessage ) {
            var itemAward = item.Award1;
            if( itemAward[0] == 'material' || itemAward[0] == 'gem' 
                || itemAward[0] == 'card' ) {
                var itemName = '';
                if( itemAward[0] == 'material' ) {
                    itemName = gConfMaterial[itemAward[1]].Name;
                }else if( itemAward[0] == 'gem' ) {
                    itemName = gConfGem[itemAward[1]].Name;
                }else if( itemAward[0] == 'card' ) {
                    itemName = gConfRole[itemAward[1]].Name;
                }

                gMessage.addSystemMessage('diamond_card', [user.info.un, itemAward[2], itemName]);
            }
        }
        
        resp.data.card = diamondCard.cards[index];
        resp.data.cash = -cashCost;
    }while(false);

    onHandled();
}

exports.diamond_card_got = function(player, req, resp, onHandled){
    do {
        var activitySchedule = findActivitySchedule('diamondcard');
        if( !activitySchedule ) {
            resp.code = 1; resp.desc = 'not open'; break;
        }
        
        var user = player.user;
        var diamondCard = user.activity.diamond_card;

        if( diamondCard.cards.length <= 0 || Object.keys(diamondCard.open).length <= 0 ) {
            resp.code = 1; resp.desc = 'no open card'; break;
        }

        var awards = [];
        for( var pos in diamondCard.open ) {
            awards.push(gConfAvDiamondCardItem[diamondCard.cards[diamondCard.open[pos]]].Award1);
        }

        diamondCard.cards = [];
        diamondCard.cash = 0;
        player.markDirty('activity.diamond_card.cards');
        player.markDirty('activity.diamond_card.cash');

        resp.data.awards = player.addAwards(awards);
    }while(false);

    onHandled();
}

exports.diamond_card_exchange = function(player, req, resp, onHandled){
    do {
        var activitySchedule = findActivitySchedule('diamondcard');
        if( !activitySchedule ) {
            resp.code = 1; resp.desc = 'not open'; break;
        }
        
        if( isNaN(req.args.id) ) {
            resp.code = 1; resp.desc = 'invalid args'; break;
        }

        var id = req.args.id;
        var diamondCardAwardConf = gConfAvDiamondCardAward[id];
        if( !diamondCardAwardConf ) {
            resp.code = 1; resp.desc = 'id error'; break;
        }

        var user = player.user;
        player.checkInventory();
        if( !player.addInventory('material', 200, -diamondCardAwardConf.Diamond) ) {
            resp.code = 1; resp.desc = 'not enough material'; break;
        }
        
        var material = {};
        material[200] = -diamondCardAwardConf.Diamond;

        resp.data.awards = player.addAwards([diamondCardAwardConf.Award1]);
        resp.data.material = material;
    }while(false);

    onHandled();
}

exports.get_server_payrank = function (player, req, resp, onHandled){
    do {
        var activitySchedule = findActivitySchedule('serverpayrank', 1);

        if( !activitySchedule ) {
            resp.code = 1; resp.desc = 'not open'; break;
        }

        var activity = player.user.activity;
        if( activity.server_payrank.time != activitySchedule.time ) {
            activity.server_payrank = {
                'time' : activitySchedule.time,
                'cash' : 0,
                'reward' : {},
            };
            player.markDirty('activity.server_payrank');
        }

        req.args.time = activitySchedule.time;
    }while(false);

    if( resp.code != 0 ) {
        onHandled();
        return;
    }
    
    req.args.server = config.ServerId - 1;
    requestCloud(req, resp, function(){
        resp.data.server_payrank = player.user.activity.server_payrank;
        onHandled();
    });
}

exports.server_payrank_reward = function (player, req, resp, onHandled){
    do {
        var activitySchedule = findActivitySchedule('serverpayrank', 2);
        if( !activitySchedule ) {
            resp.code = 1; resp.desc = 'not open'; break;
        }
        
        if( isNaN(req.args.id) ) {
            resp.code = 1; resp.desc = 'invalid args'; break;
        }

        var rewardId = Math.floor(req.args.id);
        if( !gConfAvServerPayRank[rewardId] || rewardId > 3 ) {
            resp.code = 1; resp.desc = 'invalid id'; break;
        }

        var serverPayrank = player.user.activity.server_payrank;
        if( serverPayrank.reward[rewardId] ) {
            resp.code = 1; resp.desc = 'got'; break;
        }


    }while(false);

    if( resp.code != 0 ) {
        onHandled();
        return;
    }

    req.args.server = config.ServerId - 1;
    requestCloud(req, resp, function(){

        if( resp.code == 0 ) {
            serverPayrank.reward[rewardId] = 1;
            player.markDirty('activity.server_payrank.reward');

            resp.data.awards = player.addAwards(gConfAvServerPayRank[rewardId].Awards1);
        }

        onHandled();

    });
}

exports.server_payrank_top_reward = function (player, req, resp, onHandled){
    var activitySchedule = findActivitySchedule('serverpayrank', 2);
    if( !activitySchedule ) {
        resp.code = 1; resp.desc = 'not open';
        onHandled();
        return;
    }
    req.args.server = config.ServerId - 1;
    requestCloud(req, resp, function(){
        if( resp.code == 0 ) {
            var awardConf = gConfAvServerPayRank[resp.data.rank];
            resp.data.awards = player.addAwards([awardConf.Award1, awardConf.Award2, awardConf.Award3, awardConf.Award4]);
        }
        onHandled();
    });
}

exports.mystic_shop_buy = function (player, req, resp, onHandled){
    do {
        var activitySchedule = findActivitySchedule('mysticshop');
        if( !activitySchedule ) {
            resp.code = 1; resp.desc = 'not open'; break;
        }

        var mysticShopConf = gConfAvMysticShopCost[req.args.id];
        if( !mysticShopConf ) {
            resp.code = 1; resp.desc = 'invalid id'; break;
        }

        var id = req.args.id;
        
        var user = player.user;
        var buy = user.activity.mystic_shop[id] || 0;
        var buyMax = mysticShopConf[buy+1] ? false : true;
            
        var cashCost = 0;
        if( buyMax ) {
            cashCost = mysticShopConf[buy].Cash;
        }else{
            cashCost = mysticShopConf[buy+1].Cash;
        }

        if( !player.costResource('cash', cashCost, id, buy) ) {
            resp.code = 1; resp.desc = 'not enough cash'; break;
        }

        if( !buyMax ) {
            user.activity.mystic_shop[id] = buy + 1;
            player.markDirty('activity.mystic_shop');
        }

        resp.data.cash = -cashCost;
        resp.data.awards = player.addAwards([gConfAvMysticShop[id].Award1]);

    }while(false);

    onHandled();
}

exports.get_new_year_first_pay = function(player, req, resp, onHandled){
    do {
        var newYearFirstPay = player.getActivity('newyearfirstpay');
        if (!newYearFirstPay) {
            resp.code = 1; resp.desc = 'not open'; break;
        }
        
        resp.data.new_year_first_pay = newYearFirstPay;
    }while(false);

    onHandled();
}

exports.new_year_first_pay_reward = function(player, req, resp, onHandled){
    do {
        var key = 'newyearfirstpay';
        var activityInfo = player.getActivity(key, {conf:1});
        if (!activityInfo || !activityInfo.data) {
            resp.code = 1; resp.desc = 'not open'; break;
        }

        var newYearFirstPay = activityInfo.data;
        
        var chargedCash = newYearFirstPay.cash; 
        if( chargedCash <= 0 ) {
            resp.code = 1; resp.desc = 'no reward'; break;
        }
    
        var now = common.getTime();
        var rewardDay = Math.ceil((now - activityInfo.conf.time) / 86400);
        var avNewYearFirstPayConf = gConfAvNewYearFirstPay[rewardDay];
        if( !avNewYearFirstPayConf ) {
            resp.code = 1; resp.desc = 'reward day error';break;
        }
        
        var addCash = 0;
        if( chargedCash == avNewYearFirstPayConf.Cash ) {
            addCash = Math.floor(chargedCash * avNewYearFirstPayConf.Equal / 100); 
        }else if( chargedCash > avNewYearFirstPayConf.Cash) {
            addCash = Math.floor(chargedCash * avNewYearFirstPayConf.Higher / 100); 
        }else {
            addCash = Math.floor(chargedCash * avNewYearFirstPayConf.Lower / 100); 
        }

        if( addCash > avNewYearFirstPayConf.MaxCash ) {
            addCash = avNewYearFirstPayConf.MaxCash; 
        }

        if( addCash < 0 ) {
            addCash = 0; 
        }

        player.alterResource('cash', addCash);
        
        newYearFirstPay.got = 1;
        player.saveActivityValue(key, 'got');

        resp.data.awards = [['user','cash', addCash]];

    }while(false);

    onHandled();
}

exports.get_red_packet = function (player, req, resp, onHandled){
    do {
        var activitySchedule = findActivitySchedule('redpacket');
        if( !activitySchedule ) {
            resp.code = 1; resp.desc = 'not open';break;
        }

        var user = player.user;
        var redPacket = user.activity.red_packet;
        var today = common.getDate();
        if( today != redPacket.day ) {
            redPacket = {
                'got' : {},
                'open' : 0,
                'day' :today,
            };

            user.activity.red_packet = redPacket;
            player.markDirty('activity.red_packet');
        }
        
        var dailyShopCost = user.activity.daily_shop_cost;
        if( today != dailyShopCost.day ) {
            dailyShopCost.cash = 0;
            dailyShopCost.day = today;
            player.markDirty('activity.daily_shop_cost');
        }
        
        resp.data.daily_shop_cost = dailyShopCost;
        resp.data.red_packet = redPacket;
    } while(false);

    onHandled();
}

exports.red_packet_reward = function(player, req, resp, onHandled){
    do {
        var activitySchedule = findActivitySchedule('redpacket');
        if( !activitySchedule ) {
            resp.code = 1; resp.desc = 'not open';break;
        }   
         
        if( isNaN(req.args.id) ) {
            resp.code = 1; resp.desc = 'invalid args';break;
        } 

        var rewardCash = Math.floor(req.args.id);
        var avRedPacketConf = gConfAvRedPacket[rewardCash];
        if( !avRedPacketConf ) {
            resp.code = 1; resp.desc = 'invalid cash';break;
        }

        var user = player.user;
        var redPacket = user.activity.red_packet;
        var today = common.getDate();
        if( today != redPacket.day ) {
            redPacket = {
                'got' : {},
                'open' : 0,
                'day' :today,
            };

            user.activity.red_packet = redPacket;
            player.markDirty('activity.red_packet');
        }

        if( redPacket.got[rewardCash] ) {
            resp.code = 1; resp.desc = 'have got'; break;
        }   

        var dailyShopCost = user.activity.daily_shop_cost;
        if( today != dailyShopCost.day ) {
            dailyShopCost.cash = 0;
            dailyShopCost.day = today;
            player.markDirty('activity.daily_shop_cost');
        }

        var costedCash = dailyShopCost.cash; 
        if( costedCash < rewardCash  ) {
            resp.code = 1; resp.desc = 'cost cash not enough'; break;
        }
        
        redPacket.got[rewardCash] = 1;
        
        player.markDirty(util.format('activity.red_packet.got.%d', rewardCash));
        var awards = [avRedPacketConf.Award1];
        player.addAwards(awards);

        resp.data.awards = awards; 
    }while(false);

    onHandled();
}

exports.get_lucky_number = function (player, req, resp, onHandled){
    do {
        var activitySchedule = findActivitySchedule('luckynumber');
        if( !activitySchedule ) {
            resp.code = 1; resp.desc = 'not open'; break;
        }
        
        var today = common.getDate(); 
        var luckyNumber = player.user.activity.lucky_number;
        if( luckyNumber.day != today ) {
            luckyNumber.got = 0; 
            luckyNumber.selected = 0;
            luckyNumber.day = today;
            player.markDirty('activity.lucky_number');
        }

    }while(false);

    if( resp.code != 0 ) {
        onHandled();
        return;
    }
    
    requestCloud(req, resp, onHandled);
}

exports.modify_lucky_number = function (player, req, resp, onHandled){
    do {
        var activitySchedule = findActivitySchedule('luckynumber');
        if( !activitySchedule ) {
            resp.code = 1; resp.desc = 'not open'; break;
        }
        
        var user = player.user;
        var luckyNumber = user.activity.lucky_number;
        if( luckyNumber.got ) {
            resp.code = 1; resp.desc = 'have got'; break;
        } 
        
        var cashCost = gConfGlobal.LuckyNumberModifyCash;
        if( !player.costResource('cash', cashCost) ) {
            resp.code = 1; resp.desc = 'not enough cash'; break;
        }
        
        luckyNumber.selected = 0;
        player.markDirty('activity.lucky_number.selected');
        
        resp.data.cash = -cashCost;
    }while(false);

    onHandled();
}

exports.lucky_number_reward = function (player, req, resp, onHandled){
    var user = player.user;
    do {
        var activitySchedule = findActivitySchedule('luckynumber');
        if( !activitySchedule ) {
            resp.code = 1; resp.desc = 'not open'; break;
        }
        
        var luckyNumber = user.activity.lucky_number;
        var today = common.getDate();
        if( luckyNumber.day != today ) {
            resp.code = 1; resp.desc = 'invalid day'; break;
        }

        if( luckyNumber.got ) {
            resp.code = 1; resp.desc = 'have got'; break;
        }
        
        if( !luckyNumber.selected ) {
            resp.code = 1; resp.desc = 'no selected'; break;
        }

    }while(false);

    if( resp.code != 0 ) {
        onHandled();
        return;
    }
    
    requestCloud(req, resp, function(){
        if( 0 == resp.code ) {
            if( resp.data.awards ) {
                resp.data.awards = player.addAwards(resp.data.awards);
                user.activity.lucky_number.got = 1; 
                player.markDirty('activity.lucky_number.got');
            }
        }

        onHandled();
    });
}

exports.select_lucky_number = function (player, req, resp, onHandled){
    var user = player.user; 
    do {
        var activitySchedule = findActivitySchedule('luckynumber');
        if( !activitySchedule ) {
            resp.code = 1; resp.desc = 'not open'; break;
        }
        
        var selectNumber = Math.floor(req.args.num);
        if( isNaN(selectNumber) || (selectNumber < 0) || (selectNumber > 999) ) {
            resp.code = 1; resp.desc = 'invalid args'; break;
        }
        
        if( user.activity.lucky_number.selected ) {
            resp.code = 1; resp.desc = 'have selected'; break;
        }

    }while(false);

    if( resp.code != 0 ) {
        onHandled();
        return;
    }
    
    req.args.name = user.info.un; 
    requestCloud(req, resp, function(){
        if( 0 == resp.code ) {
            user.activity.lucky_number.selected = 1; 
            player.markDirty('activity.lucky_number.selected');
        }

        onHandled();
    });
}

exports.rebirth_year_boss = function(player, req, resp, onHandled) {
    do {
        var activitySchedule = findActivitySchedule('yearboss');
        if( !activitySchedule ) {
            resp.code = 1; resp.desc = 'not open'; break;
        }

        var activityConf = gConfActivities.yearboss;
        var user = player.user;
        if( user.status.level < activityConf.OpenLevel ) {
            resp.code = 1; resp.desc = 'level limit'; break;
        }

        var cashCost = gConfGlobal.YearBossEndCoolCash;
        if (!player.costResource('cash', cashCost)) {
            resp.code = 1; resp.desc = 'not enough cash'; break;
        }

        user.activity.year_boss.cold_time = 0;
        player.markDirty('activity.year_boss.cold_time');

        resp.data.cash = -cashCost;

    }while(false);

    onHandled();
}

exports.boss_blood_year_boss = function(player, req, resp, onHandled) {
    var user = player.user;
    do{
        var activitySchedule = findActivitySchedule('yearboss');
        if( !activitySchedule ) {
            resp.code = 1; resp.desc = 'not open'; break;
        }

        var activityConf = gConfActivities.yearboss;
        if( user.status.level < activityConf.OpenLevel ) {
            resp.code = 1; resp.desc = 'level limit'; break;
        }

    }while(false);

    
    if( resp.code == 1 ) {
        onHandled();
        return;
    }

    req.args.join = user.activity.year_boss.join;
    requestWorld(req, resp, onHandled);
}

exports.get_bomb_year_boss = function(player, req, resp, onHandled) {
    do{
        var activitySchedule = findActivitySchedule('yearboss');
        if( !activitySchedule ) {
            resp.code = 1; resp.desc = 'not open'; break;
        }

        var activityConf = gConfActivities.yearboss;
        var user = player.user;
        if( user.status.level < activityConf.OpenLevel ) {
            resp.code = 1; resp.desc = 'level limit'; break;
        }

        var nowTime = common.getTime();
        var yearBoss = user.activity.year_boss;
        if( (nowTime - yearBoss.bomb_time < gConfGlobal.YearBossGetBombCoolTime * 3600) ) {
            resp.code = 1; resp.desc = 'time not reach'; break;
        }
        
        // 获取一个爆竹
        var awards = [['material', gConfGlobal.YearBossBombMaterialId, 1]];
        player.addAwards(awards);

        yearBoss.bomb_time = nowTime;
        player.markDirty('activity.year_boss.bomb_time');

        resp.data.bomb_time = nowTime;

    }while(false);

    onHandled();
}

exports.get_year_boss = function(player, req, resp, onHandled) {
    var user = player.user;
    do{
        var activitySchedule = findActivitySchedule('yearboss');
        if( !activitySchedule ) {
            resp.code = 1; resp.desc = 'not open'; break;
        }

        var activityConf = gConfActivities.yearboss;

        if( user.status.level < activityConf.OpenLevel ) {
            resp.code = 1; resp.desc = 'level limit'; break;
        }

        var nowTime = common.getTime();
        var today = new Date();

        var todayStartTime = +(new Date(today.getFullYear(), today.getMonth(), today.getDate()))/1000;
        var resetTime = todayStartTime + gConfGlobal.YearBossResetHour*3600 + 10;
        var startTime = todayStartTime + gConfGlobal.YearBossStartHour*3600 - 20;

        // 时间限制(重置到第一次开始期间不能发请求)
        if( nowTime >= resetTime && nowTime <= startTime ) {
            resp.code = 1; resp.desc = 'wrong time to get'; break;
        }
        
    }while(false);

    if( resp.code == 1 ) {
        onHandled();
        return;
    }
    
    var yearBoss = user.activity.year_boss;
    req.args.join = yearBoss.join;
    req.args.got_reward = yearBoss.got_reward;

    requestWorld(req, resp, function() {
        if( resp.code == 0 ) {
            if( resp.data.bossid && resp.data.bossid != yearBoss.join ) {

                // 重置boss
                yearBoss.join = resp.data.bossid;
                yearBoss.got_reward = 0;
                yearBoss.cold_time = 0;
                yearBoss.inspire = 0;
                player.markDirty('activity.year_boss');

                resp.data.reset = 1;
            }
        }

        onHandled();
    });
}

exports.rank_year_boss = function(player, req, resp, onHandled) {
    do{
        var activitySchedule = findActivitySchedule('yearboss');
        if( !activitySchedule ) {
            resp.code = 1; resp.desc = 'not open'; break;
        }

        var activityConf = gConfActivities.yearboss;
        var user = player.user;
        if( user.status.level < activityConf.OpenLevel ) {
            resp.code = 1; resp.desc = 'level limit'; break;
        }

    }while(false);
        
    if( resp.code == 1 ) {
        onHandled();
        return;
    }

    requestWorld(req, resp, onHandled);
}

exports.get_kill_reward_year_boss = function(player, req, resp, onHandled) {
    do{
        var activitySchedule = findActivitySchedule('yearboss');
        if( !activitySchedule ) {
            resp.code = 1; resp.desc = 'not open'; break;
        }

        var activityConf = gConfActivities.yearboss;
        var user = player.user;
        if( user.status.level < activityConf.OpenLevel ) {
            resp.code = 1; resp.desc = 'level limit'; break;
        }

    }while(false);
        
    if( resp.code == 1 ) {
        onHandled();
        return;
    }
        
    requestWorld(req, resp, function() {    
        if( resp.code == 0 ) {
            var awards = []; 
            var worldBossRewardConf = gConfYearBossReward['kill'];
            if( worldBossRewardConf ) { 
                awards.push(worldBossRewardConf.Award1);
                awards.push(worldBossRewardConf.Award2);
            }

            resp.data.awards = player.addAwards(awards);
        }

        onHandled();
    });
}

exports.get_reward_year_boss = function(player, req, resp, onHandled) {
    do {
        var activitySchedule = findActivitySchedule('yearboss');
        if( !activitySchedule ) {
            resp.code = 1; resp.desc = 'not open'; break;
        }

        var activityConf = gConfActivities.yearboss;
        var user = player.user;
        if( user.status.level < activityConf.OpenLevel ) {
            resp.code = 1; resp.desc = 'level limit'; break;
        }

    }while(false);
        
    if( resp.code == 1 ) {
        onHandled();
        return;
    }
        
    var user = player.user;
    req.args.got_reward = user.activity.year_boss.got_reward;
    requestWorld(req, resp, function() {
        if( resp.code == 0 ) {
            user.activity.year_boss.got_reward = resp.data.bossid;
            player.markDirty('activity.year_boss.got_reward');

            resp.data.awards = player.addAwards(resp.data.awards);
        }

        onHandled();
    });
}

exports.fight_year_boss = function(player, req, resp, onHandled) {
    var user = player.user;
    do {
        var activitySchedule = findActivitySchedule('yearboss');
        if( !activitySchedule ) {
            resp.code = 1; resp.desc = 'not open'; break;
        }

        var activityConf = gConfActivities.yearboss;
        if( user.status.level < activityConf.OpenLevel ) {
            resp.code = 1; resp.desc = 'level limit'; break;
        }

        var nowTime = common.getTime();
        if( (nowTime - user.activity.year_boss.cold_time) < (gConfGlobal.YearBossCoolTime-10) ) {
            resp.code = 1; resp.desc = 'in cool time'; break;
        }

        var today = new Date();
        var todayStartTime = +(new Date(today.getFullYear(), today.getMonth(), today.getDate()))/1000;
        var resetTime = todayStartTime + gConfGlobal.YearBossResetHour*3600 - 10;
        var startTime = todayStartTime + gConfGlobal.YearBossStartHour*3600 + 10;

        // 时间限制(重置到开始期间不能发请求)
        if( nowTime >= resetTime && nowTime <= startTime ) {
            resp.code = 1; resp.desc = 'wrong time to fight'; break;
        }

    }while(false);

    if( resp.code == 1 ) {
        onHandled();
        return;
    }

    req.args.join = user.activity.year_boss.join;
    requestWorld(req, resp, function() {
        if( resp.code == 0 && resp.data.time ) {
            user.activity.year_boss.cold_time = resp.data.time;
            player.markDirty('activity.year_boss.cold_time');
        }

        onHandled();
    });
}

exports.inspire_year_boss = function(player, req, resp, onHandled ) {
    do {
        var activitySchedule = findActivitySchedule('yearboss');
        if( !activitySchedule ) {
            resp.code = 1; resp.desc = 'not open'; break;
        }

        var activityConf = gConfActivities.yearboss;
        var isCash = req.args.cash ? true : false;

        var user = player.user;
        if( user.status.level < activityConf.OpenLevel ) {
            resp.code = 1; resp.desc = 'level limit'; break;
        }

        var yearBoss = user.activity.year_boss;
        // 是否超过上限
        var inspired = yearBoss.inspire * gConfGlobal.YearBossInspireAttack;
        if( inspired >= gConfGlobal.YearBossInspireLimit ) {
            resp.code=1; resp.desc='up to inspire limit'; break;
        }

        if( isCash ) {
            var cashCost = gConfGlobal.YearBossInspireCash;
            if (!player.costResource('cash', cashCost)) {
                resp.code = 1; resp.desc = 'not enough cash'; break;
            }

            resp.data.cash = -cashCost;
        }else {
            var bombCost = gConfGlobal.YearBossInspireBomb;
            if( !player.addInventory('material', gConfGlobal.YearBossBombMaterialId, -1) ) {
                resp.code = 1; resp.desc = 'not enough bomb'; break;
            }

            resp.data.bomb = -1;
        }

        yearBoss.inspire += 1;
        player.markDirty('activity.year_boss.inspire');

    }while(false);

    onHandled();
}

exports.get_richsend = function (player, req, resp, onHandled){
    do {
        var activitySchedule = findActivitySchedule('richsend', 1);
        if( !activitySchedule ) {
            resp.code = 1; resp.desc = 'not open'; break;
        }
        
        var today = common.getDate();
        var activity = player.user.activity;
        if( activity.rich_send.time != activitySchedule.time ) {
            activity.rich_send = {
                'time' : activitySchedule.time,
                'cash' : 0,
                'day' : today,
                'reward' : {},
            };
            player.markDirty('activity.rich_send');
        }else if( activity.rich_send.day != today ) {
            activity.rich_send.day = today;
            activity.rich_send.reward = {};
            player.markDirty('activity.rich_send');
        }
        requestWorld(req, resp, function() {
            resp.data.rich_send = player.user.activity.rich_send;
            onHandled();
        });
        return;
    }while(false);

    onHandled();
}

exports.richsend_reward = function (player, req, resp, onHandled){
    do {
        var activitySchedule = findActivitySchedule('richsend', 1);
        if( !activitySchedule ) {
            resp.code = 1; resp.desc = 'not open'; break;
        }

        var richSendConf = gConfAvRichSend[req.args.cash];
        if( !richSendConf ) {
            resp.code = 1; resp.desc = 'invalid cash'; break;
        }

        var cash = req.args.cash;
        var richSend = player.user.activity.rich_send;
        if( richSend.day != common.getDate() ) {
            resp.code = 1; resp.desc = 'new day'; break;
        }
        if( richSend.reward[cash] ) {
            resp.code = 1; resp.desc = 'got'; break;
        }

        requestWorld(req, resp, function(){
            if( resp.code == 0 ) {
                richSend.reward[cash] = 1;
                player.markDirty('activity.rich_send.reward');

                var awards = [];
                for( var i=1; i<=4; i++ ) {
                    awards.push(richSendConf['Award'+i]);
                }
                resp.data.awards = player.addAwards(awards);
            }

            onHandled();
        });
        
        return;
    }while(false);
    
    onHandled();
}

exports.get_richsend_top10 = function (player, req, resp, onHandled){
    do {
        var activitySchedule = findActivitySchedule('richsend', 1);
        if( !activitySchedule ) {
            resp.code = 1; resp.desc = 'not open'; break;
        }

        requestWorld(req, resp, onHandled);
        return;
    }while(false)

    onHandled();
}

exports.richsend_top10reward = function (player, req, resp, onHandled){
    var activitySchedule = findActivitySchedule('richsend', 2);
    if( !activitySchedule ) {
        resp.code = 1; resp.desc = 'not open';
        onHandled();
        return;
    }

    requestWorld(req, resp, function(){
        if( resp.code == 0 ) {
            var awardConf = gConfAvRichSendRank[resp.data.rank];
            resp.data.awards = player.addAwards([awardConf.Award1, awardConf.Award2, awardConf.Award3, awardConf.Award4]);
        }
        onHandled();
    });
}

exports.get_new_red_packet = function (player, req, resp, onHandled){
    do {
        var activitySchedule = findActivitySchedule('newredpacket');
        if( !activitySchedule ) {
            resp.code = 1; resp.desc = 'not open';break;
        }

        var user = player.user;
        var newRedPacket = user.activity.new_red_packet;
        var today = common.getDate();
        if( today != newRedPacket.day ) {
            newRedPacket = {
                'got' : {},
                'cash' : 0,
                'open' : 0,
                'day' :today,
            };

            user.activity.new_red_packet = newRedPacket;
            player.markDirty('activity.new_red_packet');
        }

        resp.data.new_red_packet = newRedPacket;
    } while(false);

    onHandled();
}

exports.new_red_packet_reward = function(player, req, resp, onHandled){
    do {
        var activitySchedule = findActivitySchedule('newredpacket');
        if( !activitySchedule ) {
            resp.code = 1; resp.desc = 'not open';break;
        }   
         
        if( isNaN(req.args.id) ) {
            resp.code = 1; resp.desc = 'invalid args';break;
        } 

        var rewardCash = Math.floor(req.args.id);
        var avNewRedPacketConf = gConfAvNewRedPacket[rewardCash];
        if( !avNewRedPacketConf ) {
            resp.code = 1; resp.desc = 'invalid cash';break;
        }

        var user = player.user;
        var newRedPacket = user.activity.new_red_packet;
        var today = common.getDate();
        if( today != newRedPacket.day ) {
            newRedPacket = {
                'got' : {},
                'open' : 0,
                'day' :today,
            };

            user.activity.new_red_packet = newRedPacket;
            player.markDirty('activity.new_red_packet');
        }

        if( newRedPacket.got[rewardCash] ) {
            resp.code = 1; resp.desc = 'have got'; break;
        }

        if (newRedPacket.cash < rewardCash) {
            resp.code = 1; resp.desc = 'cost cash not enough'; break;
        }

        //var dailyShopCost = user.activity.daily_shop_cost;
        //if( today != dailyShopCost.day ) {
        //    dailyShopCost.cash = 0;
        //    dailyShopCost.day = today;
        //    player.markDirty('activity.daily_shop_cost');
        //}

        //var costedCash = dailyShopCost.cash; 
        //if( costedCash < rewardCash  ) {
        //    resp.code = 1; resp.desc = 'cost cash not enough'; break;
        //}
        
        newRedPacket.got[rewardCash] = 1;
        
        player.markDirty(util.format('activity.new_red_packet.got.%d', rewardCash));
        var awards = [avNewRedPacketConf.Award1];
        player.addAwards(awards);

        resp.data.awards = awards; 
    }while(false);

    onHandled();
}

exports.super_card_start = function(player, req, resp, onHandled){
    do {
        var activitySchedule = findActivitySchedule('supercard');
        if( !activitySchedule ) {
            resp.code = 1; resp.desc = 'not open'; break;
        }

        var user = player.user;
        var superCard = user.activity.super_card;
        if( superCard.cards.length > 0 ) {
            resp.code = 1; resp.desc = 'not end'; break;
        }

        var useSpecial2 = ((superCard.cost2||0) >= 50000);
        var useSpecial1 = false;
        if( !useSpecial2 && (superCard.cost1||0) >= 2000) {
            useSpecial1 = true;
        }

        var cards = [];
        var special = 0;
        var confAvSuperCard = gConfAvSuperCard[activitySchedule.conf];
        for( var pos in confAvSuperCard ) {
            var cardObj = confAvSuperCard[pos];

            if( cardObj.Mark == 1 && useSpecial1 ) {
                cards.push(common.wRand(cardObj.Special)); 
                special = +pos;
            }else if( cardObj.Mark == 2 && useSpecial2 ) {
                cards.push(common.wRand(cardObj.Special)); 
                special = +pos;
            }else{
                cards.push(common.wRand(cardObj.Item));
            }
        }

        if( useSpecial1 ) {
            superCard.cost1 = 0;
        }

        if( useSpecial2 ) {
            superCard.cost2 = 0;
        }

        superCard.special = special;
        superCard.open = {};
        superCard.cards = cards;

        player.markDirty('activity.super_card');
        resp.data.cards = cards;
    }while(false);

    onHandled();
}

exports.super_card_refresh = function(player, req, resp, onHandled){
    do {
        var activitySchedule = findActivitySchedule('supercard');
        if( !activitySchedule ) {
            resp.code = 1; resp.desc = 'not open'; break;
        }

        var useCash = req.args.cash ? true : false;
        var cashCost = 0;

        var user = player.user;
        var superCard = user.activity.super_card;
        if( !useCash ) {
            if( superCard.free >= gConfGlobal.SuperCardDailyLimit ) {
                resp.code = 1; resp.desc = 'no free'; break;
            }
        }else{
            if( !gConfAvSuperCardCost[superCard.cash + 1] ) {
                resp.code = 1; resp.desc = 'no more times'; break;
            }

            cashCost = gConfAvSuperCardCost[superCard.cash+1].RefreshCash;
            if( !player.costResource('cash', cashCost, superCard.cash) ) {
                resp.code = 1; resp.desc = 'not enough cash'; break;
            }
        }

        var useSpecial2 = ((superCard.cost2||0) >= 50000);
        var useSpecial1 = false;
        if( !useSpecial2 && (superCard.cost1||0) >= 2000) {
            useSpecial1 = true;
        }

        var cards = [];
        var special = 0;
        var confAvSuperCard = gConfAvSuperCard[activitySchedule.conf];
        for( var pos in confAvSuperCard ) {
            var cardObj = confAvSuperCard[pos];

            if( cardObj.Mark == 1 && useSpecial1 ) {
                cards.push(common.wRand(cardObj.Special)); 
                special = pos;
            }else if( cardObj.Mark == 2 && useSpecial2 ) {
                cards.push(common.wRand(cardObj.Special)); 
                special = pos;
            }else{
                cards.push(common.wRand(cardObj.Item));
            }
        }

        if( useSpecial1 ) {
            superCard.cost1 = 0;
        }

        if( useSpecial2 ) {
            superCard.cost2 = 0;
        }

        superCard.special = special;
        superCard.open = {};
        superCard.cards = cards;

        if( useCash ) {
            superCard.cash += 1;
        }else{
            superCard.free += 1;
        }
        
        player.markDirty('activity.super_card');
        resp.data.cards = cards;
        resp.data.cash = -cashCost;
    }while(false);

    onHandled();
}

exports.super_card_open = function(player, req, resp, onHandled){
    do {
        var activitySchedule = findActivitySchedule('supercard');
        if( !activitySchedule ) {
            resp.code = 1; resp.desc = 'not open'; break;
        }
        
        if( isNaN(req.args.pos) ) {
            resp.code = 1; resp.desc = 'invalid args'; break;
        }

        var pos = +req.args.pos;
        var confAvSuperCard = gConfAvSuperCard[activitySchedule.conf]
        if (!confAvSuperCard[pos]) {
            resp.code = 1; resp.desc = 'invalid pos'; break;
        }
        
        var user = player.user;
        var superCard = user.activity.super_card;
        if( superCard.cards.length <= 0 ) {
            resp.code = 1; resp.desc = 'please refresh'; break;
        }

        if( pos in superCard.open ) {
            resp.code = 1; resp.desc = 'opend'; break;
        }

        var opened = Object.keys(superCard.open).length;
        if( opened >= gConfGlobal.SuperCardOpenPerRoundLimit ) {
            resp.code = 1; resp.desc = 'no more open'; break;
        }

        var cashCost = gConfAvSuperCardCost[opened+1].OpenCash;
        if( !cashCost ) {
            resp.code = 1; resp.desc = 'no more open'; break;
        }

        if( !player.costResource('cash', cashCost, opened) ) {
            resp.code = 1; resp.desc = 'not enough cash'; break;
        }

        var weights = {};
        for( var id in confAvSuperCard ) {
            weights[id-1] = confAvSuperCard[id].Weight;
        }

        for( var poss in superCard.open ) {
            delete weights[superCard.open[poss]];
        }

        var index = +common.wRand(weights);
        if( superCard.special && opened == 0 ) {
            index = superCard.special - 1;
        }

        superCard.open[pos] = index;

        player.markDirty('activity.super_card.open');

        superCard.cost1 = (superCard.cost1 || 0) + cashCost;
        player.markDirty('activity.super_card.cost1');
        
        var haveZuoCi = false;
        var roles = user.role;
        for( var rid in roles ) {
            if( rid == 279 ) {
                haveZuoCi = true; 
            }
        }

        if( !haveZuoCi ) {
            superCard.cost2 = (superCard.cost2 || 0 ) + cashCost;
            player.markDirty('activity.super_card.cost2');
        }
         
        var item = gConfAvSuperCardItem[activitySchedule.conf][superCard.cards[index]];
        if( item.SendMessage ) {
            var itemAward = item.Award1;
            if( itemAward[0] == 'material' || itemAward[0] == 'gem' 
                || itemAward[0] == 'card' ) {
                var itemName = '';
                if( itemAward[0] == 'material' ) {
                    itemName = gConfMaterial[itemAward[1]].Name;
                }else if( itemAward[0] == 'gem' ) {
                    itemName = gConfGem[itemAward[1]].Name;
                }else if( itemAward[0] == 'card' ) {
                    itemName = gConfRole[itemAward[1]].Name;
                }

                gMessage.addSystemMessage('super_card', [user.info.un, itemAward[2], itemName]);
            }
        }
        
        resp.data.card = superCard.cards[index];
        resp.data.cash = -cashCost;
    }while(false);

    onHandled();
}

exports.super_card_got = function(player, req, resp, onHandled){
    do {
        var activitySchedule = findActivitySchedule('supercard');
        if( !activitySchedule ) {
            resp.code = 1; resp.desc = 'not open'; break;
        }
        
        var user = player.user;
        var superCard = user.activity.super_card;

        if( superCard.cards.length <= 0 || Object.keys(superCard.open).length <= 0 ) {
            resp.code = 1; resp.desc = 'no open card'; break;
        }

        var awards = [];
        for( var pos in superCard.open ) {
            awards.push(gConfAvSuperCardItem[activitySchedule.conf][superCard.cards[superCard.open[pos]]].Award1);
        }

        superCard.cards = [];
        superCard.cash = 0;
        player.markDirty('activity.super_card.cards');
        player.markDirty('activity.super_card.cash');

        resp.data.awards = player.addAwards(awards);
    }while(false);

    onHandled();
}

exports.login_invest = function(player, req, resp, onHandled){
    do {
        if( isNaN(req.args.cash) ) {
            resp.code = 1; resp.desc = 'invalid args'; break;
        }

        var activitySchedule = findActivitySchedule('logininvest');
        if( !activitySchedule ) {
            resp.code = 1; resp.desc = 'not open'; break;
        }
        
        var investCash = Math.floor(req.args.cash);
        if( !(investCash in gConfAvLoginInvest) ) {
            resp.code = 1; resp.desc = 'error cash'; break;
        } 

        var user = player.user;
        var loginInvest = user.activity.login_invest;
        if( loginInvest.cash ) {
            resp.code = 1; resp.desc = 'have invested'; break;
        }

        if( !player.costResource('cash', investCash ) ){ 
            resp.code = 1; resp.desc = 'not enough cash'; break;
        }

        loginInvest.cash = investCash;
        loginInvest.count += 1;
        player.markDirty('activity.login_invest.cash');
        player.markDirty('activity.login_invest.count');

    }while(false);

    onHandled();
}

exports.login_invest_reward = function(player, req, resp, onHandled){
    do {
        if( isNaN(req.args.day) ) {
            resp.code = 1; resp.desc = 'invalid args'; break;
        }
        
        var rewardDay = Math.floor(req.args.day);
        var user = player.user;
        var loginInvest = user.activity.login_invest;
        var avLoginInvestConf = gConfAvLoginInvest[loginInvest.cash];
        if( !avLoginInvestConf || !avLoginInvestConf['Cash'+rewardDay] ) {
            resp.code = 1; resp.desc = 'no reward'; break;
        }

        if( loginInvest.count < rewardDay ) {
            resp.code = 1; resp.desc = 'not reach'; break;
        }

        if( rewardDay in loginInvest.got ) {
            resp.code = 1; resp.desc = 'have got'; break;
        }

        loginInvest.got[rewardDay] = 1;
        player.markDirty('activity.login_invest.got');

        resp.data.awards = player.addAwards([['user', 'cash', avLoginInvestConf['Cash'+rewardDay]]]);
    }while(false);

    onHandled();
}

exports.level_invest = function(player, req, resp, onHandled){
    do {
        if( isNaN(req.args.cash) ) {
            resp.code = 1; resp.desc = 'invalid args'; break;
        }

        var activitySchedule = findActivitySchedule('levelinvest');
        if( !activitySchedule ) {
            resp.code = 1; resp.desc = 'not open'; break;
        }
        
        var investCash = Math.floor(req.args.cash);
        if( !(investCash in gConfAvLevelInvest) ) {
            resp.code = 1; resp.desc = 'error cash'; break;
        } 

        var user = player.user;
        var levelInvest = user.activity.level_invest;
        if( levelInvest.cash ) {
            resp.code = 1; resp.desc = 'have invested'; break;
        }

        if( !player.costResource('cash', investCash ) ){ 
            resp.code = 1; resp.desc = 'not enough cash'; break;
        }

        levelInvest.cash = investCash;
        player.markDirty('activity.level_invest.cash');

    }while(false);

    onHandled();
}

exports.level_invest_reward = function(player, req, resp, onHandled){
    do {
        if( isNaN(req.args.level) ) {
            resp.code = 1; resp.desc = 'invalid args'; break;
        }
        
        var rewardLevel = Math.floor(req.args.level);
        var user = player.user;
        var levelInvest = user.activity.level_invest;
        var avLevelInvestConf = gConfAvLevelInvest[levelInvest.cash];
        if( !avLevelInvestConf || !avLevelInvestConf['Cash'+rewardLevel] ) {
            resp.code = 1; resp.desc = 'no reward'; break;
        }

        if( user.status.level < rewardLevel ) {
            resp.code = 1; resp.desc = 'not reach'; break;
        }

        if( rewardLevel in levelInvest.got ) {
            resp.code = 1; resp.desc = 'have got'; break;
        }
        
        levelInvest.got[rewardLevel] = 1;
        player.markDirty('activity.level_invest.got');

        resp.data.awards = player.addAwards([['user', 'cash', avLevelInvestConf['Cash'+rewardLevel]]]);
    }while(false);

    onHandled();
}

exports.dragon_wish = function(player, req, resp, onHandled){
    do {
        var user = player.user;
        if( !user.mark.hasOwnProperty('dragon') ) {
            resp.code = 1; resp.desc = 'no dragon'; break;
        } 
        
        var nextDragon = user.mark.dragon + 1;
        if( !gConfDragonWish[nextDragon] ) {
            resp.code = 1; resp.desc = 'no more wish'; break;
        }

        user.mark.dragon = nextDragon;
        player.markDirty('mark.dragon');

        resp.data.awards = player.addAwards([gConfDragonWish[nextDragon].Award1]);
    }while(false);

    onHandled();
}

exports.new_firstpay_reward = function(player, req, resp, onHandled){
    do {
        if( isNaN(req.args.cash) ) {
            resp.code = 1; resp.desc = 'invalid args'; break;
        }

        var rewardCash = Math.floor(req.args.cash);
        var user = player.user;
        var newFirstPay = user.activity.new_first_pay;
        var avNewFirstPayConf = gConfAvNewFirstPay[rewardCash];
        if( !avNewFirstPayConf ) {
            resp.code = 1; resp.desc = 'cash error'; break;
        }

        if( !newFirstPay.hasOwnProperty(rewardCash) ) {
            resp.code = 1; resp.desc = 'no reward'; break;
        }

        if( newFirstPay[rewardCash] ) {
            resp.code = 1; resp.desc = 'have got'; break;
        }
        
        newFirstPay[rewardCash]= 1;
        player.markDirty(util.format('activity.new_first_pay.%d', rewardCash));
        
        var awards = [];
        for( var i=1; i<=10; i++ ) {
            var award = avNewFirstPayConf['Award'+i];
            if( !award ) continue;
            awards.push(award);
        }

        resp.data.awards = player.addAwards(awards);
    }while(false);

    onHandled();
}

exports.get_new_forge_reward = function(player, req, resp, onHandled){
    do {
        if( isNaN(req.args.id) || !gConfAvNewForgeLevel[req.args.id] ) {
            resp.code = 1; resp.desc = 'invalid args'; break;
        }
        
        var rewardId = parseInt(req.args.id);
        var activitySchedule = findActivitySchedule('forgelevel');
        if( !activitySchedule ) {
            resp.code = 1; resp.desc = 'not open'; break;
        }

        var user = player.user;
        var activitiesConf = gConfActivities.forgelevel;
        if( user.status.level < activitiesConf.OpenLevel ) {
            resp.code = 1; resp.desc = 'level not reach'; break;
        }
        
        var newForgeLevel = user.activity.new_forge_level;
        
        if( rewardId in newForgeLevel.got ) {
            resp.code = 1; resp.desc = 'have got'; break;
        }

        var avNewForgeLevelConf = gConfAvNewForgeLevel[rewardId];
        var rewardType = avNewForgeLevelConf.Type;
        var rewardLevel = avNewForgeLevelConf.Level;
        
        var haveReward = true;
        if( 'all' == rewardType ) {
            // 所有装备都打造成功后, 可领取的额外奖励 
            for( var id in gConfAvNewForgeLevel ) {
                if( +id == rewardId  ) {
                    continue; 
                }

                if( !newForgeLevel.got[id] ) {
                    haveReward = false;
                    break;
                } 
            }

        }else {
            if( newForgeLevel.equip[rewardType] < rewardLevel ) {
                haveReward = false;
            }
        }

        if( !haveReward ) {
            resp.code = 1; resp.desc = 'no reward'; break;
        }
        
        newForgeLevel.got[rewardId] = 1;
        player.markDirty(util.format('activity.new_forge_level.got.%d', rewardId));

        resp.data.awards = player.addAwards([avNewForgeLevelConf.Award1]);
    }while(false);

    onHandled();
}

exports.get_league_king = function(player, req, resp, onHandled){
    do {            
        var user = player.user;
        if( user.activity.league_king ) {
            resp.data.league_king = user.activity.league_king;    
        }       
    }while(false);  

    onHandled();
}
            
exports.get_league_king_reward= function(player, req, resp, onHandled) {
    do {    
        if( isNaN(req.args.id) ) {
            resp.code = 1; resp.desc = 'invalid args'; break;
        }

        var rewardId = req.args.id;
        var user = player.user;

        if( !user.activity.league_king || !(rewardId in user.activity.league_king) ) {
            resp.code = 1; resp.desc = 'no reward'; break;
        }       
        
        var avLeagueKingConf = gConfAvLeagueKing[rewardId];
        if( !avLeagueKingConf ) {
            resp.code = 1; resp.desc = 'id error'; break;
        }
            
        var leagueKing = user.activity.league_king;
        if( leagueKing[rewardId] ) {
            resp.code = 1; resp.desc = 'have got'; break;
        }   
        
        leagueKing[rewardId] = 1;
        player.markDirty(util.format('activity.league_king.%d', rewardId));
        
        var awards = [avLeagueKingConf.Award1, avLeagueKingConf.Award2];
        if( leagueKing.leader_group && (+leagueKing.leader_group == rewardId) ) {
            awards.push(avLeagueKingConf.Award1); 
            awards.push(avLeagueKingConf.Award2); 
        }
                
        resp.data.awards = player.addAwards(awards);
    }while(false);

    onHandled();
}

exports.get_qq_panel_reward = function(player, req, resp, onHandled){
    do {
        var user = player.user;
        if( user.activity.qq_panel ) {
            resp.code = 1; resp.desc = 'have got'; break;
        }

        user.activity.qq_panel = 1;
        player.markDirty('activity.qq_panel');
        
        //神将碎片*1 超级将魂包*1 神兽丹*1 幸运宝石*1 黄金令*10
        resp.data.awards = player.addAwards([['material',47,1],['material',55,1],['material',78,1],['material',37,1],['material',48,10]]);
    }while(false);

    onHandled();
}

exports.get_facebook_feed_reward = function(player, req, resp, onHandled){
    do {
        var user = player.user;
        if( user.activity.facebook_feed ) {
            resp.code = 1; resp.desc = 'have got'; break;
        }

        user.activity.facebook_feed = 1;
        player.markDirty('activity.facebook_feed');
        
        //小喇叭*1 洗髓丹*1 将魂*500 金币*100000 黄金令*1
        resp.data.awards = player.addAwards([['material',38,1],['material',20,1],['user','soul',500],['user','gold',100000],['material',48,1]]);
    }while(false);
    onHandled();
}

exports.get_dig_treasure = function (player, req, resp, onHandled){
    do {
        var activitySchedule = findActivitySchedule('digtreasure');
        if( !activitySchedule ) {
            resp.code = 1; resp.desc = 'not open';break;
        }

        var user = player.user;
        var digTreasure = user.activity.dig_treasure;
        if( activitySchedule.time != digTreasure.time ) {
            digTreasure.depth = 1;
            digTreasure.axe= 0;
            // 位置1默认为起点位置,ID为1,表示为空地
            digTreasure.open = {
                1:{
                    id:1, 
                    got:1
                },
            };
            digTreasure.time = activitySchedule.time; 
            digTreasure.day = 0; 

            player.markDirty('activity.dig_treasure');
        }

        var today = common.getDate();
        if( today != digTreasure.day ) {
            digTreasure.day = today;
            digTreasure.axe += gConfGlobal.DigTreasureDailyAxe;

            player.markDirty('activity.dig_treasure.day');
            player.markDirty('activity.dig_treasure.axe');
        }
        
        resp.data.dig_treasure = digTreasure;
    } while(false);

    onHandled();
}

exports.open_dig_treasure = function (player, req, resp, onHandled){
    do {
        var activitySchedule = findActivitySchedule('digtreasure');
        if( !activitySchedule ) {
            resp.code = 1; resp.desc = 'not open';break;
        }
         
        if( isNaN(req.args.pos) ) {
            resp.code = 1; resp.desc = 'invalid args';break;
        }

        var openPos = Math.floor(req.args.pos);
        if( openPos < 2 || openPos > 36 ) {
            resp.code = 1; resp.desc = 'pos err ';break;
        }

        var isCash = req.args.cash ? true : false;

        var user = player.user;
        var digTreasure = user.activity.dig_treasure;
        var digTreasureOpen = digTreasure.open;
        if( openPos in digTreasureOpen ) {
            resp.code = 1; resp.desc = 'have open';break;
        }

        // 检验openPos 是否合法
        var isOpenPosValid = false;
        var openedPos = openPos - 1;
        if( (openedPos in digTreasureOpen) && 
            [10, 19, 28].indexOf(openPos) < 0 ) {
            isOpenPosValid = true; 
        }
        
        openedPos = openPos + 1;
        if( !isOpenPosValid && (openedPos in digTreasureOpen) && 
            [9, 18, 27, 36].indexOf(openPos) < 0 ) {
            isOpenPosValid = true; 
        }

        openedPos = openPos - 9;
        if( !isOpenPosValid && (openedPos in digTreasureOpen) ) {
            isOpenPosValid = true; 
        }

        openedPos = openPos + 9;
        if( !isOpenPosValid && (openedPos in digTreasureOpen) ) {
            isOpenPosValid = true; 
        }

        if( !isOpenPosValid ) {
            resp.code = 1; resp.desc = 'invalide pos';break;
        }

        // 随机挖宝 
        var costAxeNum = gConfAvDigTreasureAxe[digTreasure.depth].NeedAxe;
        var ownAxeNum = digTreasure.axe;
        var costCash = 0;
        if( (ownAxeNum < costAxeNum) && !isCash ) {
            resp.code = 1; resp.desc = 'not enough axe';break;
        }else if( (ownAxeNum < costAxeNum) && isCash ) {
            costCash = gConfGlobal.DigTreasureBuyCash; 
            if( !player.costResource('cash', costCash, digTreasure.depth)  ) {
                resp.code = 1; resp.desc = 'not enough cash';break;
            }

            if( gConfGlobal.DigTreasureBuyAxeNum + ownAxeNum < costAxeNum ) {
                resp.code = 1; resp.desc = 'not enough axe';break;
            }

            digTreasure.axe += gConfGlobal.DigTreasureBuyAxeNum;
        }
        
        digTreasure.axe -= costAxeNum;
        player.markDirty('activity.dig_treasure.axe');
        
        var rewardId = 0;
        var isDoorOpen = false; 
        for( var pos in digTreasureOpen ) {
            if( +digTreasureOpen[pos].id != DigTreasureDoorId )  continue;
            isDoorOpen = true; break;
        }

        var openedPosNum = Object.keys(digTreasureOpen).length;        
        if( gConfAvDigTreasureAxe[digTreasure.depth + 1] && !isDoorOpen 
            && (openedPosNum >= 32) ) {
            // 当下层的通道没有打开且当前层打开的位置数大于等于32时
            isDoorOpen = (Math.random() > 0.5)  ? true : false;
            if( isDoorOpen || !isDoorOpen && (35 == openedPosNum) ) {
                isDoorOpen = true;
                rewardId = DigTreasureDoorId; 
            }
        }

        if( 0 == rewardId ) {
            var weights = {};
            for( var id in gConfAvDigTreasure ) {
                if( (+id == DigTreasureDoorId) && 
                    (isDoorOpen || !gConfAvDigTreasureAxe[digTreasure.depth + 1] ) )  continue;
                weights[id] = gConfAvDigTreasure[id]['Weight' + digTreasure.depth]; 
            }
            rewardId = +common.wRand(weights);
        }

        var avDigTreasureConf = gConfAvDigTreasure[rewardId];
        var rewardType = avDigTreasureConf.Type;
        if( 'material' == rewardType ) {
            resp.data.awards = player.addAwards([avDigTreasureConf.Award1]);
        }
        
        if( 'thief' == rewardType || 'door' == rewardType ) {
            digTreasure.open[openPos] = {
                'id' : rewardId,
                'got' : 0,
            }
        }else if( 'material' == rewardType || 'space' == rewardType ) {
            digTreasure.open[openPos] = {
                'id' : rewardId,
                'got' : 1,
            }
        }

        player.markDirty(util.format('activity.dig_treasure.open.%d', openPos));
        
        if( gConfAvDigTreasure[rewardId].SendMessage ) {
            var itemAward = avDigTreasureConf.Award1;
            var itemName = '';
            if( itemAward[0] == 'material' ) {
                itemName = gConfMaterial[itemAward[1]].Name;
            }else if( itemAward[0] == 'gem' ) {
                itemName = gConfGem[itemAward[1]].Name;
            }else if( itemAward[0] == 'card' ) {
                itemName = gConfRole[itemAward[1]].Name;
            }
            gMessage.addSystemMessage('dig_treasure', [user.info.un, itemAward[2], itemName]);
        }

        resp.data.id = rewardId;
        resp.data.cash = -costCash;

    } while(false);

    onHandled();
}

exports.fight_dig_treasure = function (player, req, resp, onHandled){
    do {
        var activitySchedule = findActivitySchedule('digtreasure');
        if( !activitySchedule ) {
            resp.code = 1; resp.desc = 'not open';break;
        }
        
        if( isNaN(req.args.pos)  ) {
            resp.code = 1; resp.desc = 'invalid args';break;
        }

        var openedPos = Math.floor(req.args.pos);

        var user = player.user;
        var digTreasure = user.activity.dig_treasure;
        var digTreasureOpen = digTreasure.open;

        if( !(openedPos in digTreasureOpen) ) {
            resp.code = 1; resp.desc = 'args error';break;
        }

        var bossId = digTreasureOpen[openedPos].id;
        if( !(bossId in gConfAvDigTreasureThief) ) {
            resp.code = 1; resp.desc = 'pos error';break;
        }

        if( digTreasureOpen[openedPos].got ) {
            resp.code = 1; resp.desc = 'have got';break;
        }
        
        var avDigTreasureThiefConf = gConfAvDigTreasureThief[bossId];
        var attacker = new Fighter();
        var defender = new Fighter();

        attacker.initWithPlayer(player);
        defender.initWithMonster(batModMap.DIGTREASURE, bossId, avDigTreasureThiefConf);

        var battleReport = attacker.fight(defender);
        if( battleReport.success ) {
            digTreasureOpen[openedPos].got = 1;
            player.markDirty(util.format('activity.dig_treasure.open.%d.got', openedPos));
            resp.data.awards = player.addAwards([avDigTreasureThiefConf.Award1, avDigTreasureThiefConf.Award2, avDigTreasureThiefConf.Award3]);
        }
        
        resp.data.battle = battleReport;

    } while(false);

    onHandled();
}

exports.enter_next_dig_treasure = function (player, req, resp, onHandled){
    do {
        var activitySchedule = findActivitySchedule('digtreasure');
        if( !activitySchedule ) {
            resp.code = 1; resp.desc = 'not open';break;
        }
        
        var user = player.user;
        var digTreasure = user.activity.dig_treasure;
        if( !gConfAvDigTreasureAxe[digTreasure.depth + 1] ) {
            resp.code = 1; resp.desc = 'to max';break;
        }
        
        var digTreasureOpen = digTreasure.open;
        var isDoorOpen = false; 
        for( var pos in digTreasureOpen ) {
            if( +digTreasureOpen[pos].id != DigTreasureDoorId )  continue;
            isDoorOpen = true; break;
        }

        if( !isDoorOpen ) {
            resp.code = 1; resp.desc = 'no door';break;
        }

        digTreasure.depth += 1;
        digTreasure.open = {
            1:{
                id:1, 
                got:1
            },
        };

        player.markDirty('activity.dig_treasure.depth');
        player.markDirty('activity.dig_treasure.open');

        resp.data.dig_treasure = digTreasure;
    } while(false);

    onHandled();
}

exports.reset_dig_treasure = function (player, req, resp, onHandled){
    do {
        var activitySchedule = findActivitySchedule('digtreasure');
        if( !activitySchedule ) {
            resp.code = 1; resp.desc = 'not open';break;
        }
        
        var isCash = req.args.cash ? true : false;
        var user = player.user;
        var digTreasure = user.activity.dig_treasure;

        if( !isCash && (digTreasure.free >= gConfGlobal.DigTreasureFreeResetLimit) ) {
            resp.code = 1; resp.desc = 'no more free'; break;
        }

        if( !isCash ) {
            digTreasure.free += 1; 
            player.markDirty('activity.dig_treasure.free');
        }else {
            var confBuy = gConfBuy[digTreasure.cash + 1]; 
            if( !confBuy ) {
                resp.code = 1; resp.desc = 'no more to buy'; break;
            }
            
            costCash = confBuy.CashDigTreasureReset;
            if( !costCash ) {
                resp.code = 1; resp.desc = 'no more to buy'; break;
            }

            if( !player.costResource('cash', costCash, digTreasure.depth, digTreasure.cash) ){
                resp.code = 1; resp.desc = 'not enough cash'; break;
            }

            digTreasure.cash += 1;
            player.markDirty('activity.dig_treasure.cash');

        }

        digTreasure.depth = 1;
        digTreasure.open = {
            1:{
                id:1, 
                got:1
            },
        };

        player.markDirty('activity.dig_treasure.depth');
        player.markDirty('activity.dig_treasure.open');
        
        resp.data.dig_treasure = digTreasure;
    } while(false);

    onHandled();
}

exports.buy_axe_dig_treasure = function (player, req, resp, onHandled){
    do {
        var activitySchedule = findActivitySchedule('digtreasure');
        if( !activitySchedule ) {
            resp.code = 1; resp.desc = 'not open';break;
        }

        var user = player.user;
        var digTreasure = user.activity.dig_treasure;
        var costCash = gConfGlobal.DigTreasureBuyCash;
        if( !player.costResource('cash', costCash) ) {
            resp.code = 1; resp.desc = 'cash not enough';break;
        }

        digTreasure.axe += gConfGlobal.DigTreasureBuyAxeNum;
        player.markDirty('activity.dig_treasure.axe');

        resp.data.cash = -costCash;
    } while(false);

    onHandled();
}

exports.get_pet_cost = function (player, req, resp, onHandled) {
    do {
        var activitySchedule = findActivitySchedule('petcost');
        if( !activitySchedule ) {
            resp.code = 1; resp.desc = 'not open';break;
        }

        var user = player.user;
        var activitiesConf = gConfActivities.petcost;
        if( user.status.level < activitiesConf.OpenLevel ) {
            resp.code = 1; resp.desc = 'level not reach'; break;
        }

        var petCost = user.activity.pet_cost;
        if( petCost.time != activitySchedule.time ) {
            petCost.time = activitySchedule.time ; 
            petCost.got = 0;
            petCost.used = {};
            player.markDirty('activity.pet_cost');
        }

        resp.data.pet_cost = petCost; 

    } while(false);

    onHandled();
}

exports.get_pet_cost_reward = function (player, req, resp, onHandled) {
    do { 
        var activitySchedule = findActivitySchedule('petcost');
        if( !activitySchedule ) {
            resp.code = 1; resp.desc = 'not open';break;
        }

        if( isNaN(req.args.level) ) {
            resp.code = 1; resp.desc = 'args invalid';break;
        }        

        var user = player.user;
        var activitiesConf = gConfActivities.petcost;
        if( user.status.level < activitiesConf.OpenLevel ) {
            resp.code = 1; resp.desc = 'level not reach'; break;
        }

        var petCost = user.activity.pet_cost;
        if( petCost.time != activitySchedule.time ) {
            resp.code = 1; resp.desc = 'old time';break;
        }

        if( petCost.got ) { 
            resp.code = 1; resp.desc = 'has got';break;
        } 

        var confId = activitySchedule.conf;
        var level = Math.floor(req.args.level);
        if( !gConfAvPetCost[confId] || !gConfAvPetCost[confId][level] ) {
            resp.code = 1; resp.desc = 'confId or level invalid';break;
        }

        var pet = user.pet;
        if( pet.level < level ) {
            resp.code = 1; resp.desc = 'pet level not reach';break;
        }

        var lastLevel = level - 1;
        if( !petCost.used[lastLevel] ) { 
            resp.code = 1; resp.desc = 'no used';break;
        } 

        var petConf = gConfPet[lastLevel];
        if( !petConf || !petConf.Material ) {
            resp.code = 1; resp.desc = 'invalid last level';break;
        }

        petCost.got = level;
        player.markDirty('activity.pet_cost.got');

        resp.data.awards = player.addAwards([ ['material', petConf.Material, petCost.used[lastLevel]] ]);
    } while(false);

    onHandled();
}

exports.get_vip_box = function ( player, req, resp, onHandled) {
    do {
        var activitySchedule = findActivitySchedule('vipbox');
        if( !activitySchedule ) {
            resp.code = 1; resp.desc = 'not open';break;
        }

        var user = player.user;
        var confActivities = gConfActivities.vipbox;
        if( user.status.level < confActivities.OpenLevel ) {
            resp.code = 1; resp.desc = 'level not reach'; break;
        }

        var vipBox = user.activity.vip_box;
        if( vipBox.time != activitySchedule.time ) {
            vipBox.time = activitySchedule.time;             
            vipBox.box_count = {};
            player.markDirty('activity.vip_box');
        }

        resp.data.vipbox = vipBox;
    } while(false);

    onHandled();
}

exports.buy_vip_box = function ( player, req, resp, onHandled) {
    do {
        var activitySchedule = findActivitySchedule('vipbox');
        if( !activitySchedule ) {
            resp.code = 1; resp.desc = 'not open';break;
        }

        var user = player.user;
        var confActivities = gConfActivities.vipbox;
        if( user.status.level < confActivities.OpenLevel ) {
            resp.code = 1; resp.desc = 'level not reach'; break;
        }

        var vipBox = user.activity.vip_box;
        if( vipBox.time != activitySchedule.time ) {
            resp.code = 1; resp.desc = 'old time'; break;
        }

        if( isNaN(req.args.id) ) {
            resp.code = 1; resp.desc = 'id invalid'; break;
        }

        var id = Math.floor(req.args.id);
        var confAvVipBox = gConfAvVipBox[id];
        if( !confAvVipBox ) {
            resp.code = 1; resp.desc = 'id error'; break;
        }

        if( user.status.vip < confAvVipBox.Level ) {
            resp.code = 1; resp.desc = 'vip level not reach.'; break;
        }
        
        var haveBuy = vipBox.box_count[id] || 0;
        if( haveBuy >= confAvVipBox.LimitNum ) {
            resp.code = 1; resp.desc = 'to max.'; break;
        }

        var cashCost = confAvVipBox.Cash2;
        if (!player.costResource('cash', cashCost, id)) {
            resp.code = 1; resp.desc = 'cash not enough.'; break;
        }

        if( !(id in vipBox.box_count) ) {
            vipBox.box_count[id] = 0; 
        }

        vipBox.box_count[id] += 1;
        player.markDirty( util.format('activity.vip_box.box_count.%d',id));

        resp.data.awards = player.addAwards( [confAvVipBox.Award1] );
        resp.data.cash = -cashCost;
    } while(false);

    onHandled();
}

exports.get_all_gift = function( player, req, resp, onHandled) {
    do {
        var activitySchedule = findActivitySchedule('allgift');
        if( !activitySchedule ) {
            resp.code = 1; resp.desc = 'not open'; break;
        }

        var user = player.user;
        var activitiesConf = gConfActivities.allgift;
        if( user.status.level < activitiesConf.OpenLevel ) {
            resp.code = 1; resp.desc = 'level not reach'; break;
        }
        
        var today = common.getDate();
        var allGift = user.activity.all_gift;
        if( allGift.time != activitySchedule.time ) {
            allGift = {
                'time' : activitySchedule.time,
                'day' : today,
                'paid' : 0,
                'got' : {
                    'all' : 0,
                    'self' : 0,
                },
            };

            user.activity.all_gift = allGift;
            player.markDirty('activity.all_gift');

        }else if( allGift.day != today ) {
            allGift.day = today;
            allGift.paid = 0;
            allGift.got = {
                'all' : 0,
                'self' : 0,
            };

            player.markDirty('activity.all_gift');
        }

        requestWorld(req, resp, function() {
            resp.data.all_gift = allGift;
            onHandled();
        });

        return;
    }while(false);

    onHandled();
};

exports.get_all_gift_reward = function( player, req, resp, onHandled) {
    do {
        var awardType = req.args.type ? req.args.type : '';
        if( !('all' == awardType || 'self' == awardType ) ) {
            resp.code = 1; resp.desc = 'invalid args'; break;
        } 

        var activitySchedule = findActivitySchedule('allgift');
        if( !activitySchedule ) {
            resp.code = 1; resp.desc = 'not open'; break;
        }

        var user = player.user;
        var activitiesConf = gConfActivities.allgift;
        if( user.status.level < activitiesConf.OpenLevel ) {
            resp.code = 1; resp.desc = 'level not reach'; break;
        }
        
        var today = common.getDate();
        var allGift = user.activity.all_gift;
        if( allGift.time != activitySchedule.time || allGift.day != today ) {
            resp.code = 1; resp.desc = 'time or day error'; break;
        }

        if( allGift.got[awardType] ) {
            resp.code = 1; resp.desc = 'has got'; break;
        }

        var confId = activitySchedule.conf;
        var activityDayPassed = common.getDayPassed( activitySchedule.time );
        var avAllGiftConf = (gConfAvAllGift[confId] ? gConfAvAllGift[confId][activityDayPassed] : null);
        if( !avAllGiftConf ) {
            resp.code = 1; resp.desc = 'passed day error'; break;
        }

        if( 'self' == awardType && allGift.paid < avAllGiftConf['self'].PayMin ) {
            resp.code = 1; resp.desc = 'not reach self gift'; break;
        }

        req.args.cash = avAllGiftConf['all'].PayMin || 0;
        requestWorld(req, resp, function() {
            if( resp.code == 0 ) {

                allGift.got[awardType] = 1;
                player.markDirty(util.format('activity.all_gift.got.%s',awardType));
            
                var allGiftConf = avAllGiftConf[awardType];
                var awards = [ allGiftConf.Award1, allGiftConf.Award2, allGiftConf.Award3, allGiftConf.Award4 ];
                resp.data.awards = player.addAwards( awards );
            }
            onHandled();
        });

        return;
    }while(false);

    onHandled();
};

exports.lucky_circle_refresh = function(player, req, resp, onHandled){
    do {
        var activitySchedule = findActivitySchedule('luckycircle');
        if( !activitySchedule ) {
            resp.code = 1; resp.desc = 'not open'; break;
        }

        var user = player.user;
        var luckyCircle = user.activity.lucky_circle;

        if( luckyCircle.time != activitySchedule.time ) {
            luckyCircle = {
                'score' : 0,
                'items' : [],
                'count' : 0,
                'color' : {
                    'green' : 0,
                    'orange': 0,
                    'purple': 0,
                    'red'   : 0,
                },
                'got' : {
                    'green' : 0,
                    'orange': 0,
                    'purple': 0,
                    'red'   : 0,
                },
                'cash': 0,
                'update_time': 0,
                'time': activitySchedule.time,
                'day' : common.getDate(),
            };

            user.activity.lucky_circle = luckyCircle;
            player.markDirty('activity.lucky_circle');
        }
        
        if( luckyCircle.day != common.getDate() ) {
            user.activity.lucky_circle.cash = 0;
            user.activity.lucky_circle.color = {
                'green' : 0,
                'orange': 0,
                'purple': 0,
                'red'   : 0,
            };
            user.activity.lucky_circle.got = {
                'green' : 0,
                'orange': 0,
                'purple': 0,
                'red'   : 0,
            };
            user.activity.lucky_circle.day = common.getDate();
            user.activity.lucky_circle.count = 0;
            player.markDirty('activity.lucky_circle.cash');
            player.markDirty('activity.lucky_circle.color');
            player.markDirty('activity.lucky_circle.got');
            player.markDirty('activity.lucky_circle.day');
            player.markDirty('activity.lucky_circle.count');

            resp.data.lucky_circle = user.activity.lucky_circle;
            break;
        }

        var useCash = req.args.cash ? true : false;
        var cashCost = 0;

        if( !useCash ) {
            var now = common.getTime();
            if( (now - luckyCircle.update_time) < gConfGlobal.LuckyCircleFreeUpdateTime * 3600 - 10 ) {
                resp.code = 1; resp.desc = 'time not reach'; break;
            }

            luckyCircle.update_time = now;
            player.markDirty('activity.lucky_circle.update_time');
        }else{
            if( !gConfAvLuckyCircleCost[luckyCircle.cash + 1] ) {
                cashCost = gConfAvLuckyCircleCost.max.RefreshCash;
            }else {
                cashCost = gConfAvLuckyCircleCost[luckyCircle.cash+1].RefreshCash;
            }

            if( !player.costResource('cash', cashCost, luckyCircle.cash) ) {
                resp.code = 1; resp.desc = 'not enough cash'; break;
            }
        }
        
        var items = [];
        for( var id in gConfAvLuckyCircle ) {
            var avLuckyCircleConf = gConfAvLuckyCircle[id]; 
            var selectItemWeights = {};
            for( var itemId in avLuckyCircleConf.Item ) {
                var avLuckyCircleItemConf = gConfAvLuckyCircleItem[itemId];
                if( avLuckyCircleItemConf.RoleId && !user.role[avLuckyCircleItemConf.RoleId] )
                    continue;

                selectItemWeights[itemId] = avLuckyCircleItemConf.Weight;
            }

            items.push(common.wRand(selectItemWeights));
        }

        //items = items.sort(function(a, b){ return (Math.random() > 0.5) ? 1 : -1;});
        
        luckyCircle.items = items;
        luckyCircle.count = 0;
        player.markDirty('activity.lucky_circle.items');
        player.markDirty('activity.lucky_circle.count');

        if( useCash ) {
            luckyCircle.cash += 1;
            player.markDirty('activity.lucky_circle.cash');
        }        

        resp.data.items = items;
        resp.data.cash = -cashCost;
        resp.data.update_time = luckyCircle.update_time;
        resp.data.lucky_circle = user.activity.lucky_circle;
    }while(false);

    onHandled();
}

exports.lucky_circle_start = function(player, req, resp, onHandled){
    do {
        var activitySchedule = findActivitySchedule('luckycircle');
        if( !activitySchedule ) {
            resp.code = 1; resp.desc = 'not open'; break;
        }

        var startCount = req.args.ten ? 10 : 1;

        var user = player.user;
        var luckyCircle = user.activity.lucky_circle;
        if( luckyCircle.time != activitySchedule.time ) {
            resp.code = 1; resp.desc = 'time error'; break;
        }

        var luckyCircleCount = luckyCircle.count;

        var cashCost = 0;
        var scoreCost = 0;

        for( var i = 0; i < startCount; i++ ) {
            var luckyCircleCostConf = gConfAvLuckyCircleCost[luckyCircleCount + 1];
            if( !luckyCircleCostConf ) {
                cashCost += gConfAvLuckyCircleCost.max.Cash;
                scoreCost += gConfAvLuckyCircleCost.max.Score;
            }else {
                cashCost += luckyCircleCostConf.Cash;
                scoreCost += luckyCircleCostConf.Score;
            }
            
            luckyCircleCount += 1;
        }

        if( (user.status.cash < cashCost) || (luckyCircle.score < scoreCost) ) {
            resp.code = 1; resp.desc = 'not enough cash or score'; break;
        }

        // 格子抽到的权重
        var selectCircleFieldWeights = {}
        for( var id in gConfAvLuckyCircle ) {
            selectCircleFieldWeights[id]  = gConfAvLuckyCircle[id].Weight;
        }

        var selectItems = luckyCircle.items;
        var selectItemsLength = selectItems.length;
        var changeColors = {};
        var ids = [];
        var awards = [];
        for( var i = 0; i < startCount; i++ ) {
            var index = +common.wRand(selectCircleFieldWeights) - 1;
            ids.push(index);
            var changeColor = gConfAvLuckyCircle[index+1].Color;
            changeColors[changeColor] = 1;
            luckyCircle.color[changeColor] += 1;

            var avLuckyCircleItemConf = gConfAvLuckyCircleItem[selectItems[index]];
            var itemAward = avLuckyCircleItemConf.Award1;

            awards.push(itemAward);
            if( avLuckyCircleItemConf.SendMessage ) {
                if( itemAward[0] == 'material' || itemAward[0] == 'gem' 
                    || itemAward[0] == 'card' ) {
                    var itemName = '';
                    if( itemAward[0] == 'material' ) {
                        itemName = gConfMaterial[itemAward[1]].Name;
                    }else if( itemAward[0] == 'gem' ) {
                        itemName = gConfGem[itemAward[1]].Name;
                    }else if( itemAward[0] == 'card' ) {
                        itemName = gConfRole[itemAward[1]].Name;
                    }

                    gMessage.addSystemMessage('lucky_circle', [user.info.un, itemAward[2], itemName]);
                }
            }
        }

        for( var color in changeColors ) {
            player.markDirty(util.format('activity.lucky_circle.color.%s', color));
        }

        player.costResource('cash', cashCost, startCount);

        luckyCircle.score -= scoreCost;
        luckyCircle.count = luckyCircleCount;
        player.markDirty('activity.lucky_circle.count');
        player.markDirty('activity.lucky_circle.score');


        resp.data.awards = player.addAwards(awards);
        resp.data.cash = -cashCost;
        resp.data.score = -scoreCost;
        resp.data.ids = ids;
    }while(false);

    onHandled();
}

exports.lucky_circle_reward = function(player, req, resp, onHandled){
    do {
        var activitySchedule = findActivitySchedule('luckycircle');
        if( !activitySchedule ) {
            resp.code = 1; resp.desc = 'not open'; break;
        }
         
        if( isNaN(req.args.id) ) {
            resp.code = 1; resp.desc = 'invalid args'; break;
        }

        var id = req.args.id;
        var luckyCircleAwardConf = gConfAvLuckyCircleAward[id];
        if( !luckyCircleAwardConf ) {
            resp.code = 1; resp.desc = 'id error'; break;
        }

        var user = player.user;
        var luckyCircle = user.activity.lucky_circle;
        if( luckyCircle.time != activitySchedule.time ) {
            resp.code = 1; resp.desc = 'time error'; break;
        }

        var color = luckyCircleAwardConf.Color; 
        var count = luckyCircleAwardConf.Count;
        if( luckyCircle.got[color] ) {
            resp.code = 1; resp.desc = 'have got'; break;
        }

        if( luckyCircle.color[color] < count ) {
            resp.code = 1; resp.desc = 'not enough color'; break;
        }

        luckyCircle.got[color] = 1;
        player.markDirty(util.format('activity.lucky_circle.got.%s', color));

        resp.data.awards = player.addAwards([luckyCircleAwardConf.Award1]);

    }while(false);

    onHandled();
}

exports.lucky_circle_exchange = function(player, req, resp, onHandled){
    do {
        var activitySchedule = findActivitySchedule('luckycircle');
        if( !activitySchedule ) {
            resp.code = 1; resp.desc = 'not open'; break;
        }
        
        var user = player.user;
        var luckyCircle = user.activity.lucky_circle;
        if( luckyCircle.time != activitySchedule.time ) {
            resp.code = 1; resp.desc = 'time error'; break;
        }

        if( isNaN(req.args.id) || isNaN(req.args.num) ) {
            resp.code = 1; resp.desc = 'invalid args'; break;
        }

        var id = req.args.id;
        var num = parseInt(req.args.num);
        if( num <=0 ) {
            resp.code = 1; resp.desc = 'num error'; break;
        }

        var luckyCircleScoreConf = gConfAvLuckyCircleScore[id];
        if( !luckyCircleScoreConf ) {
            resp.code = 1; resp.desc = 'id error'; break;
        }

        var award = luckyCircleScoreConf.Award1;
        var materialId = luckyCircleScoreConf.MaterialId;  
        if( !player.addInventory('material', materialId, -num) ) {
            resp.code = 1; resp.desc = 'not enough material'; break;
        }
        
        var material = {};
        material[materialId] = -num;
        
        var addScore = num * luckyCircleScoreConf.Score;
        user.activity.lucky_circle.score += addScore;
        player.markDirty('activity.lucky_circle.score');

        resp.data.score = addScore;
    }while(false);

    onHandled();
}

exports.get_all_charge = function(player, req, resp, onHandled){
    var user = player.user;
    do {
        var activitySchedule = findActivitySchedule('allcharge');
        if( !activitySchedule ) {
            resp.code = 1; resp.desc = 'not open'; break;
        }

        var allCharge = user.activity.all_charge;

        if( allCharge.time != activitySchedule.time ) {
            allCharge =  {
                'cash' : 0,
                'time' : activitySchedule.time,
                'got' : {},
            };

            user.activity.all_charge = allCharge;
            player.markDirty('activity.all_charge');
        }

    }while(false);

    if( resp.code == 1 ) {
        onHandled();
        return;
    }

    requestWorld(req, resp, function() {
        if( resp.code == 0 ) {
            resp.data.all_charge = user.activity.all_charge;
        }

        onHandled();
    });
}

exports.all_charge_reward = function(player, req, resp, onHandled){
    var id = 0;
    var user = player.user;
    var allCharge = user.activity.all_charge;
    do {
        var activitySchedule = findActivitySchedule('allcharge');
        if( !activitySchedule ) {
            resp.code = 1; resp.desc = 'not open'; break;
        }

        if( isNaN(req.args.id) ) {
            resp.code = 1; resp.desc = 'args error'; break;
        }

        id = req.args.id;
        
        var avAllChargeConf = gConfAvAllCharge[id];
        if( !avAllChargeConf ) {
            resp.code = 1; resp.desc = 'id error'; break;
        }

        if( allCharge.got[id] ) {
            resp.code = 1; resp.desc = 'have got'; break;
        }

    }while(false);

    if( resp.code == 1 ) {
        onHandled();
        return;
    }

    requestWorld(req, resp, function() {
        if( resp.code == 0 ) {
            allCharge.got[id] = 1;
            player.markDirty(util.format('activity.all_charge.got.%d', id));
            
            var awards = [avAllChargeConf.Award1, avAllChargeConf.Award2, avAllChargeConf.Award3, avAllChargeConf.Award4];
            resp.data.awards =  player.addAwards(awards);
        }
        onHandled();
    });
}

exports.get_year_feed_back = function(player, req, resp, onHandled){
    var user = player.user;
    do {
        var activitySchedule = findActivitySchedule('yearfeedback');
        if( !activitySchedule ) {
            resp.code = 1; resp.desc = 'not open'; break;
        }

        var yearFeedBack = user.activity.year_feed_back;

        if( yearFeedBack.time != activitySchedule.time ) {
            yearFeedBack =  {
                'cash' : 0,
                'time' : activitySchedule.time,
                'got' : {},
            };

            user.activity.year_feed_back = yearFeedBack;
            player.markDirty('activity.year_feed_back');
        }

    }while(false);

    if( resp.code == 1 ) {
        onHandled();
        return;
    }

    requestWorld(req, resp, function() {
        if( resp.code == 0 ) {
            resp.data.year_feed_back = user.activity.year_feed_back;
        }
        onHandled();
    });
}

exports.year_feed_back_reward = function(player, req, resp, onHandled){
    var id = 0;
    var user = player.user;
    var yearFeedBack = user.activity.year_feed_back;
    do {
        var activitySchedule = findActivitySchedule('yearfeedback');
        if( !activitySchedule ) {
            resp.code = 1; resp.desc = 'not open'; break;
        }

        if( isNaN(req.args.id) ) {
            resp.code = 1; resp.desc = 'args error'; break;
        }

        id = req.args.id;
        
        var avYearFeedBackConf = gConfAvYearFeedBack[id];
        if( !avYearFeedBackConf ) {
            resp.code = 1; resp.desc = 'id error'; break;
        }

        if( yearFeedBack.got[id] ) {
            resp.code = 1; resp.desc = 'have got'; break;
        }

    }while(false);

    if( resp.code == 1 ) {
        onHandled();
        return;
    }

    requestWorld(req, resp, function() {
        if( resp.code == 0 ) {
            yearFeedBack.got[id] = 1;
            player.markDirty(util.format('activity.year_feed_back.got.%d', id));
            
            var awards = [avYearFeedBackConf.Award1,avYearFeedBackConf.Award2, avYearFeedBackConf.Award3,avYearFeedBackConf.Award4,avYearFeedBackConf.Award5];
            resp.data.awards =  player.addAwards(awards);
        }
        onHandled();
    });
}

exports.national_seven_get = function(player, req, resp, onHandled) {
    do {
        var activitySchedule = findActivitySchedule('nationalseven');
        if (!activitySchedule) {
            resp.code = 1; resp.desc = 'not open'; break;
        }

        var user = player.user;
        if (user.activity.national_seven.time != activitySchedule.time) {
            resp.code = 1; resp.desc = 'need login again'; break;
        }

        resp.data.national_seven = player.user.activity.national_seven;
    } while (false);

    onHandled() && onHandled();
}

exports.national_seven_reward = function(player, req, resp, onHandled) {
    do {
        var activitySchedule = findActivitySchedule('nationalseven');
        if (!activitySchedule) {
            resp.code = 1; resp.desc = 'not open'; break;
        }
        
        if (!req.args.id) {
            resp.code = 1; resp.desc = 'param id null'; break;
        }

        var id = req.args.id;
        var user = player.user;
        if (user.activity.national_seven.time != activitySchedule.time) {
            resp.code = 1; resp.desc = 'need login again'; break;
        }

        var nationalSeven = player.user.activity.national_seven;
        if (nationalSeven.got[id]) {
            resp.code = 1; resp.desc = 'got'; break;
        }

        var rewardConf = gConfAvNationalSevenAward[id];
        if (!rewardConf) {
            resp.code = 1; resp.desc = 'id invalid'; break;
        }

        if (!isNaN(id)) {
            var dayIndex = 1 + (new Date()).getDays() - Date.createFromStamp(activitySchedule.time).getDays();
            if (dayIndex < +(id)) {
                resp.code = 1; resp.desc = 'day mismatching'; break;
            }
        } else if ('three' == id) {
            if (nationalSeven.day < 3) {
                resp.code = 1; resp.desc = 'less day'; break;
            }
        } else if ('seven' == id) {
            if (nationalSeven.day < 7) {
                resp.code = 1; resp.desc = 'less day'; break;
            }
        }

        awards = [rewardConf.Award1, rewardConf.Award2, rewardConf.Award3];
        resp.data.awards = player.addAwards(awards);

        nationalSeven.got[id] = 1;
        player.markDirty(util.format('activity.national_seven.got.%s', id)); 
    
    } while (false);

    onHandled && onHandled();
}

exports.get_standard_activity_info = function(player, req, resp, onHandled) {
    do {
        var key = req.args.key;
        if (!key) {
            resp.code = 1; resp.desc = 'req key invalid'; break;
        }

        var activityInfo = player.getActivity(key, {conf:true, delay:1});
        if (!activityInfo || !activityInfo.data) {
            resp.code = 1; resp.desc = 'activity not open'; break;
        }

        resp.data[key] = activityInfo.data;

        var dailyVars = player.getActivityDailyVars(key);
        if (dailyVars) {
            resp.data.daily_vars = dailyVars;
        }

        var specInfo = gSpecActivitys[key];
        if (specInfo && specInfo.worldArgs) {
            req.args.time = activityInfo.data.time;
            for (var i = 0, len = specInfo.worldArgs.length; i < len; ++i) {
                var item = specInfo.worldArgs[i];
                req.args[item] = activityInfo.data[item];
            }
            var worldResp = {};
            requestWorld(req, worldResp, function() {
                resp.data[key+'world'] = worldResp.data[key];
                onHandled && onHandled();
                return;
            });
            return;
        }
    } while (false);
    
    onHandled && onHandled();
}

exports.returnlevelup_get_award = function(player, req, resp, onHandled) {
    do {
        var type = req.args.type;
        if (!type) {
            resp.code = 1; resp.desc = 'req type invalid'; break;
        }

        var activityKey = 'returnlevelup';
        var activityInfo = player.getActivity(activityKey, {conf:true});
        if (!activityInfo || !activityInfo.data) {
            resp.code = 1; resp.desc = 'activity not open'; break;
        }
        
        var user = player.user;
        var activity = activityInfo.data;
        var avConfs = gConfAvReturnLevelup[activityInfo.conf.conf];
        var leaveDays = Math.min(avConfs.MaxLeaveDays, activity.leave_days);
        var avConf = avConfs[leaveDays];

        if (activity[type]) {
            resp.code = 1; resp.desc = 'award got'; break;
        }

        var awards = [];
        if ('return_award' == type) {
            for (var i = 1; i <= 12; ++i) {
                var award = avConf['Award'+i];
                if (award) {
                    awards.push(award);
                }
            }

            if (activity.old_level >= avConf.LevelLimit) {
                var award = avConf['AwardExt1'];
                if (award) {
                    awards.push(award);
                }
            }

            if (user.status.vip >= avConf.DoubleVIP) {
                awards = exCloneObj(awards);
                for (var i = 0, len = awards.length; i < len; ++i) {
                    awards[i][2] *= 2;
                }
            }
        } else if ('login_award' == type) {
            if (activity.login_days < gConfGlobal.ReturnLevelupLoginAwardNeedDays) {
                resp.code = 1; resp.desc = 'lack of days'; break;
            }

            for (var i = 1; i <= 4; ++i) {
                var award = avConf['AwardLogin'+i];
                if (award) {
                    awards.push(award);
                }
            }
        } else {
            resp.code = 1; resp.desc = 'type value invalid'; break;
        }

        activity[type] = 1;
        player.saveActivityValue(activityKey, type);
        resp.data.awards = player.addAwards(awards);
    } while (false);
    
    onHandled && onHandled();
}

exports.returnlevelup_auto_levelup = function(player, req, resp, onHandled) {
    do {
        var activityInfo = player.getActivity('returnlevelup', {conf:true});
        if (!activityInfo || !activityInfo.data) {
            resp.code = 1; resp.desc = 'activity not open'; break;
        }

        var user = player.user;
        var activity = activityInfo.data;
        var avConfs = gConfAvReturnLevelup[activityInfo.conf.conf];
        var leaveDays = Math.min(avConfs.MaxLeaveDays, activity.leave_days);
        var avConf = avConfs[leaveDays];

        if (user.status.vip < avConf.LevelupVIP) {
            resp.code = 1; resp.desc = 'vip limit'; break;
        }

        var addXp = gConfLevel[avConf.LevelLimit-1].Xp - user.status.xp;
        if (addXp <= 0) {
            resp.code = 1; resp.desc = 'user level limit'; break;
        }

        player.addXp(addXp);
        resp.data.xp = addXp;
        resp.data.level = user.status.level;
    } while (false);
    
    onHandled && onHandled();
}

exports.newservergift_get_award = function(player, req, resp, onHandled) {
    do {
        var activityKey = 'newservergift';
        var activityInfo = player.getActivity(activityKey, {conf:true});
        if (!activityInfo || !activityInfo.data) {
            resp.code = 1; resp.desc = 'activity not open'; break;
        }
        
        var user = player.user;
        var activity = activityInfo.data;
        if (activity.level_award) {
            resp.code = 1; resp.desc = 'award got'; break;
        }

        var avConf = gConfAvNewServerGift[activityInfo.conf.conf];
        var awards = [];
        for (var i = 1; i <= 3; ++i) {
            var award = avConf['Award'+i];
            if (award) {
                awards.push(award);
            }
        }

        activity.level_award = 1;
        player.saveActivityValue(activityKey, 'level_award');
        resp.data.awards = player.addAwards(awards);
    } while (false);
    
    onHandled && onHandled();
}

exports.godgift_get_award = function(player, req, resp, onHandled) {
    do {
        if (!req.args.type) {
            resp.code = 1; resp.desc = 'arg type invalid'; break;
        }

        var awardType = req.args.type;
        var awardId = +req.args.id || 0;

        var activityKey = 'godgift';
        var activityInfo = player.getActivity(activityKey, {conf:true});
        if (!activityInfo || !activityInfo.data) {
            resp.code = 1; resp.desc = 'activity not open'; break;
        }
        
        var user = player.user;
        var activity = activityInfo.data;
        var confId = activityInfo.conf.conf;

        if ('times' == awardType) {
            if (activity.times_award <= 0) {
                resp.code = 1; resp.desc = 'no times'; break;
            }

            var avConf = gConfAvGodGift[activityInfo.conf.conf];
            var awards = [];
            for (var i = 1; i <=3; ++i) {
                var award = avConf['Award'+i];
                if (award) {
                    awards.push(award);
                }
            }
            resp.data.awards = player.addAwards(awards);

            activity.times_award--;
            player.saveActivityValue(activityKey, 'times_award');
            onHandled && onHandled();

        } else if ('count' == awardType) {
            if (activity.count_award >= awardId) {
                resp.code = 1; resp.desc = 'count award got'; break;
            }

            var avGodGiftConf = gConfAvGodGift[confId];
            var avConf = gConfAvGodGiftCount[confId][awardId];
            if (!avConf) {
                resp.code = 1; resp.desc = 'invalid award id'; break;
            }

            var roles = user.role;
            var godRoleCount = 0;
            for (var rid in roles) {
                if (roles[rid].god >= avGodGiftConf.GodLevel) {
                    godRoleCount++;
                }
            }
            
            if (godRoleCount < awardId) {
                resp.code = 1; resp.desc = 'god role not enough'; break;
            }

            var awards = [];
            for (var i = 1; i <=3; ++i) {
                var award = avConf['Award'+i];
                if (award) {
                    awards.push(award);
                }
            }
            resp.data.awards = player.addAwards(awards);

            activity.count_award = awardId;
            player.saveActivityValue(activityKey, 'count_award');
            onHandled && onHandled();

        } else if ('server' == awardType) {
            if (activity.server_award) {
                resp.code = 1; resp.desc = 'server award got'; break;
            }
            
            var avConf = gConfAvGodGift[activityInfo.conf.conf];
            player.getWorldActivity(activityKey, activityInfo.conf.time, function (worldActivity) {
                do {
                    if (!worldActivity) {
                        resp.code = 1; resp.desc = 'server award except'; break;
                    }
                    
                    var serverAwakeCount = worldActivity.server_count || 0;
                    if (serverAwakeCount < avConf.ServerAwardGodNeed) {
                        resp.code = 1; resp.desc = 'server god not enough'; break;
                    }

                    var awards = [];
                    for (var i = 1; i <=3; ++i) {
                        var award = avConf['AwardServer'+i];
                        if (award) {
                            awards.push(award);
                        }
                    }
                    resp.data.awards = player.addAwards(awards);

                    activity.server_award = 1;
                    player.saveActivityValue(activityKey, 'server_award');
                } while (false);

                onHandled && onHandled();
            });
        } else {
            resp.code = 1; resp.desc = 'type invalid'; break;
        }

    } while (false);

    if (resp.code != 0) {
        onHandled && onHandled();
    }
}

exports.luckycharge_refresh = function(player, req, resp, onHandled) {
    do {
        var activityKey = 'luckycharge';
        var activityInfo = player.getActivity(activityKey, {conf:true});
        if (!activityInfo || !activityInfo.data) {
            resp.code = 1; resp.desc = 'activity not open'; break;
        }
        
        var user = player.user;
        var activity = activityInfo.data;
        var confId = activityInfo.conf.conf;
       
        var times = Math.min(gConfRuntime.LuckyChargeTimesMax, activity.refresh_times + 1);
        var scoreCost = gConfAvLuckyChargeCost[times].RefreshCost;

        if (activity.score < scoreCost) {
            resp.code = 1; resp.desc = 'score not enough'; break;
        }

        var items = [];
        var conf = gConfAvLuckyCharge[confId];
        for (var pos in conf) {
            var posConf = conf[pos];
            var weights = posConf.ItemWeights;
            if (posConf.ExistCard) {
                weights = clone(weights);
                for (var id in weights) {
                    var itemAwards = gConfAvLuckyChargeItem[confId][id].Award1;
                    if (itemAwards && 'card' == itemAwards[0] && !(itemAwards[1] in user.role)) {
                        weights[id] = 0;
                    }
                }
            }
            items.push(common.wRand(weights));
        }

        activity.score -= scoreCost;
        activity.refresh_times += 1;
        activity.cur_throw_times = 0;
        activity.items = items;
        activity.last_pos = 0;
        activity.cur_multiple = 1;
        player.saveActivityValue(activityKey, 'score');
        player.saveActivityValue(activityKey, 'refresh_times');
        player.saveActivityValue(activityKey, 'cur_throw_times');
        player.saveActivityValue(activityKey, 'items');
        player.saveActivityValue(activityKey, 'last_pos');
        player.saveActivityValue(activityKey, 'cur_multiple');

        resp.data[activityKey] = activity;
    } while (false);
    
    onHandled && onHandled();
}

exports.luckycharge_throw = function(player, req, resp, onHandled) {
    do {
        var activityKey = 'luckycharge';
        var activityInfo = player.getActivity(activityKey, {conf:true});
        if (!activityInfo || !activityInfo.data) {
            resp.code = 1; resp.desc = 'activity not open'; break;
        }
        
        var user = player.user;
        var activity = activityInfo.data;
        var confId = activityInfo.conf.conf;
       
        var times = Math.min(gConfRuntime.LuckyChargeTimesMax, activity.cur_throw_times + 1);
        var scoreCost = gConfAvLuckyChargeCost[times].ThrowCost;

        if (activity.score < scoreCost) {
            resp.code = 1; resp.desc = 'score not enough'; break;
        }

        var pos = common.wRand(gConfRuntime.LuckyChargePosWeights[confId]);

        var itemId = activity.items[pos-1];
        var itemConf = gConfAvLuckyChargeItem[confId][itemId];

        var respAwards = null;
        var awardConf = itemConf.Award1;
        if (awardConf) {
            if (activity.cur_multiple > 1) {
                awardConf = clone(awardConf);
                awardConf[2] *= activity.cur_multiple;
            }
            activity.cur_multiple = 1;
            activity.cur_throw_times = 0;
            var awards=[];
            awards.push(awardConf);
            respAwards = player.addAwards(awards);
        } else {
            activity.cur_multiple *= parseInt(itemConf.Multiple);
            activity.cur_throw_times += 1;
            respAwards = [['multiple', itemId, 1]];
        }

        resp.data.pos = pos;
        resp.data.awards = respAwards;

        activity.score -= scoreCost;
        activity.throw_times += 1;
        activity.last_pos = pos;
        player.saveActivityValue(activityKey, 'score');
        player.saveActivityValue(activityKey, 'throw_times');
        player.saveActivityValue(activityKey, 'cur_throw_times');
        player.saveActivityValue(activityKey, 'last_pos');
        player.saveActivityValue(activityKey, 'cur_multiple');

        if (itemConf.SendMessage) {
            var itemName = null;
            var itemNum = 1;
            if (awardConf) {
                var awardType = awardConf[0];
                if ('material' == awardType) {
                    itemName = gConfMaterial[awardConf[1]].Name;
                } else if('gem' == awardType) {
                    itemName = gConfGem[awardConf[1]].Name;
                } else if('card' == awardType) {
                    itemName = gConfRole[awardConf[1]].Name;
                }
                itemNum = awardConf[2];
            } else {
                itemName = itemConf.Desc;
            }

            if (itemName) {
                gMessage.addSystemMessage('luckycharge_throw', [user.info.un, itemNum, itemName]);
            }
        }

        if (activity.throw_times >= gConfRuntime.LuckyChargeRankThrowMin[confId]) {
            var worldReq = {
                uid: req.uid,
                mod: 'activity',
                act: 'luckycharge_update_rank',
                args: {
                    'conf': confId,
                    'time': activityInfo.data.time,
                    'times': activity.throw_times,
                }
            }

            var worldResp = {};
            requestWorld(worldReq, worldResp, function() {
                onHandled && onHandled();
            });
            return; 
        }
    } while (false);

    onHandled && onHandled();
}

exports.luckycharge_get_rank = function(player, req, resp, onHandled) {
    do {
        var activityKey = 'luckycharge';
        var activitySchedule = findActivitySchedule(activityKey, 1);

        if (!activitySchedule) {
            resp.code = 1; resp.desc = 'time not reach'; break;
        }

        req.args.time = activitySchedule.time;
        requestWorld(req, resp, function(){
            onHandled && onHandled();
        });
        return;
    } while (false);

    onHandled && onHandled();
}

exports.luckycharge_get_rank_award = function(player, req, resp, onHandled) {
    do {
        var activityKey = 'luckycharge';
        activitySchedule = findActivitySchedule(activityKey, 2);

        if (!activitySchedule) {
            resp.code = 1; resp.desc = 'time not reach'; break;
        }

        req.args.time = activitySchedule.time;
        requestWorld(req, resp, function(){
            if (0 == resp.code) {
                var id = resp.data.id;
                var avConfRank = gConfAvLuckyChargeRank[activitySchedule.conf][id];

                var awards = [];
                for (var i = 1; i <= 3; ++i) {
                    var award = avConfRank['Award'+i];
                    if (award) {
                        awards.push(award);
                    }
                }

                resp.data.awards = player.addAwards(awards);
            }
            onHandled && onHandled();
        });
        return;
    } while (false);

    onHandled && onHandled();
}

exports.worshipsaint_get_daily_award = function(player, req, resp, onHandled) {
    do {
        var key = 'worshipsaint';
        var activity = player.getActivity(key);
        if (!activity) {
            resp.code = 1; resp.desc = 'activity not open'; break;
        }

        var dailyVars = player.user.daily_vars;
        if (!dailyVars.pay_cash) {
            resp.code = 1; resp.desc = 'not pay'; break;
        }

        if (dailyVars.worshipsaint_award) {
            resp.code = 1; resp.desc = 'got'; break;
        }

        var dayPassed = Date.getDayPassed(activity.time);
        var avConf = gConfAvWorshipSaintDaily[dayPassed];
        if (!avConf) {
            resp.code = 1; resp.desc = 'overdue'; break;
        }

        dailyVars.worshipsaint_award = 1;
        player.markDirty('daily_vars.worshipsaint_award');

        var awards = [];
        for (var i = 1; i <= 3; ++i) {
            var award = avConf['AwardCharge'+i];
            if (award) {
                awards.push(award);
            }
        }

        resp.data.awards = player.addAwards(awards);
    } while (false);

    onHandled && onHandled();
}

exports.worshipsaint_get_level_award = function(player, req, resp, onHandled) {
    do {
        var key = 'worshipsaint';
        var activity = player.getActivity(key);
        if (!activity) {
            resp.code = 1; resp.desc = 'activity not open'; break;
        }

        var nowStamp = Date.getStamp();
        if (-1 == activity.saint_level) {
            resp.code = 1; resp.desc = 'completed'; break;
        }

        if (nowStamp < activity.saint_time) {
            resp.code = 1; resp.desc = 'not reach'; break;
        }

        var avConf = gConfAvWorshipSaintLevel[activity.saint_level];
        var awards = [];
        for (var i = 1; i <= 4; ++i) {
            var award = avConf['Award'+i];
            if (award) {
                awards.push(award);
            }
        }

        var nextLevelConf = gConfAvWorshipSaintLevel[activity.saint_level + 1];
        if (!nextLevelConf) {
            activity.saint_level = -1;
            activity.saint_time = 0;
        } else {
            activity.saint_level++;
            activity.saint_time = nowStamp + nextLevelConf.NeedTime;
        }

        player.saveActivityValue(key, 'saint_level');
        player.saveActivityValue(key, 'saint_time');

        resp.data.awards = player.addAwards(awards);
        resp.data.worshipsaint = activity;
    } while (false);

    onHandled && onHandled();
}

exports.worshipsaint_worship = function(player, req, resp, onHandled) {
    do {
        var key = 'worshipsaint';
        var activity = player.getActivity(key);
        if (!activity) {
            resp.code = 1; resp.desc = 'activity not open'; break;
        }

        if (-1 == activity.saint_level) {
            resp.code = 1; resp.desc = 'completed'; break;
        }

        var dayPassed = Date.getDayPassed(activity.time);
        var avDailyConf = gConfAvWorshipSaintDaily[dayPassed];
        if (!avDailyConf) {
            resp.code = 1; resp.desc = 'overdue'; break;
        }

        var dailyVars = player.user.daily_vars;
        if (!dailyVars.pay_cash) {
            resp.code = 1; resp.desc = 'not pay'; break;
        }

        var totalTimes = Math.floor(dailyVars.pay_cash/gConfGlobal.WorshipSaintNeedPayCash) + 1;
        var usedTimes = dailyVars.worshipsaint_times||0;
        if (usedTimes >= totalTimes) {
            resp.code = 1; resp.desc = 'no times'; break;
        }

        dailyVars.worshipsaint_times = usedTimes + 1;
        player.markDirty('daily_vars.worshipsaint_times');

        var avLevelConf = gConfAvWorshipSaintLevel[activity.saint_level];
        activity.saint_time -= avLevelConf.WorshipTime;
        player.saveActivityValue(key, 'saint_time');

        var awards = [];
        for (var i = 1; i <= 3; ++i) {
            var award = avDailyConf['AwardWorship'+i];
            if (award) {
                awards.push(award);
            }
        }

        resp.data.awards = player.addAwards(awards);
        resp.data.saint_time = activity.saint_time;
    } while (false);

    onHandled && onHandled();
}

exports.imperialexamination_start = function(player, req, resp, onHandled) {
    do {
        var key = 'imperialexamination';
        var activity = player.getActivity(key);
        if (!activity) {
            resp.code = 1; resp.desc = 'activity not open'; break;
        }

        if (activity.question) {
            resp.code = 1; resp.desc = 'started'; break;
        }

        if (activity.correct >= gConfGlobal.ImperialexaminationCorrect ||
            activity.mistake >= gConfGlobal.ImperialexaminationMistake) {
            resp.code = 1; resp.desc = 'completed'; break;
        }

        var nowTime = new Date();
        var startTime = new Date();
        var endTime = new Date();

        startTime.setFloatTime(gConfGlobal.ImperialexaminationTimeStart, 0, 0);
        endTime.setFloatTime(gConfGlobal.ImperialexaminationTimeStart + gConfGlobal.ImperialexaminationTimeLast, 0, 0);

        if (nowTime < startTime || nowTime > endTime) {
            resp.code = 1; resp.desc = 'over'; break;
        }

        activity.question = common.randValue(gConfRuntime.ImperialExaminationQuestionCount) + 1;
        player.saveActivityValue(key, 'question');
        resp.data.question = activity.question;
    } while (false);

    onHandled && onHandled();
}

exports.imperialexamination_answer = function(player, req, resp, onHandled) {
    do {
        var key = 'imperialexamination';
        var activity = player.getActivity(key);
        if (!activity) {
            resp.code = 1; resp.desc = 'activity not open'; break;
        }
    
        var check = req.args.check;
        if (!check) {
            resp.code = 1; resp.desc = 'args invalid'; break;
        }

        if (!activity.question) {
            resp.code = 1; resp.desc = 'not start'; break;
        }

        if (activity.correct >= gConfGlobal.ImperialexaminationCorrect ||
            activity.mistake >= gConfGlobal.ImperialexaminationMistake) {
            resp.code = 1; resp.desc = 'completed'; break;
        }

        var nowTime = new Date();
        var startTime = new Date();
        var endTime = new Date();

        startTime.setFloatTime(gConfGlobal.ImperialexaminationTimeStart, 0, 0);
        endTime.setFloatTime(gConfGlobal.ImperialexaminationTimeStart + gConfGlobal.ImperialexaminationTimeLast, 0, 10);

        if (nowTime < startTime || nowTime > endTime) {
            resp.code = 1; resp.desc = 'over'; break;
        }

        var isUseToken = ('D' == check);
        if (isUseToken) {
            if (activity.token < 1) {
                resp.code = 1; resp.desc = 'token not enough'; break;
            }

            activity.token--;
            player.saveActivityValue(key, 'token');
        }
        
        var questionConf = gConfImperialExaminationQA[activity.question];
        if (isUseToken || check == questionConf.Answer) {
            activity.correct++;
            activity.score += gConfGlobal.ImperialexaminationQuestionScore;
            player.saveActivityValue(key, 'correct');
            player.saveActivityValue(key, 'score');
        } else {
            activity.mistake++;
            player.saveActivityValue(key, 'mistake');
        }

        if (check == questionConf.Answer) {
            addAttrValue(activity, 'correctStreak', 1);
            if (activity.correctStreak%3 == 0) {
                activity.token++;
                player.saveActivityValue(key, 'token');
            }
        } else {
            activity.correctStreak = 0;
        }
        player.saveActivityValue(key, 'correctStreak');

        if (activity.correct >= gConfGlobal.ImperialexaminationCorrect ||
            activity.mistake >= gConfGlobal.ImperialexaminationMistake) {
            activity.question = 0;
        } else {
            activity.question = common.randValue(gConfRuntime.ImperialExaminationQuestionCount) + 1;
        }
        player.saveActivityValue(key, 'question');

        resp.data.imperialexamination = activity;

        if (activity.correct >= gConfGlobal.ImperialexaminationCorrect) {
            var worldReq = {
                uid: req.uid,
                mod: 'activity',
                act: 'imperialexamination_update_rank',
                args: {
                    'time': activity.time,
                    'round': activity.round,
                }
            }

            var worldResp = {};
            requestWorld(worldReq, worldResp, function() {
                onHandled && onHandled();
            });
            return; 
        }
    } while (false);

    onHandled && onHandled();
}

exports.imperialexamination_exchange = function(player, req, resp, onHandled) {
    do {
        if (isNaN(req.args.id) || isNaN(req.args.num)) {
            resp.code = 1; resp.desc = 'args invalid'; break;
        }
        var id = +req.args.id;
        var num = +req.args.num;
        
        var key = 'imperialexamination';
        var activity = player.getActivity(key);
        if (!activity) {
            resp.code = 1; resp.desc = 'activity not open'; break;
        }
        
        var cost = 0;
        var conf = gConfImperialExaminationExchange[id];
        if (conf.Award1) {
            cost = conf.Cost*num;
            if (activity.score < cost) {
                resp.code = 1; resp.desc = 'score not enough'; break;
            } 

            activity.score -= cost;
            player.saveActivityValue(key, 'score');

            var award = clone(conf.Award1);
            award[2] *= num;
            var awards = [award];

            resp.data.score = -cost;
            resp.data.awards = player.addAwards(awards);
        } else {
            cost = conf.Cost*num;
            if (!player.costResource('cash', cost)) {
                resp.code = 1; resp.desc = 'cash not enough'; break;
            }

            activity.token += num;
            player.saveActivityValue(key, 'token');

            resp.data.cash = -cost;
            resp.data.token = num;
        }
    } while (false);

    onHandled && onHandled();
}

exports.imperialexamination_rank_award = function(player, req, resp, onHandled) {
    do {
        var key = 'imperialexamination';
        var activity = player.getActivity(key);
        if (!activity) {
            resp.code = 1; resp.desc = 'activity not open'; break;
        }

        req.args.time = activity.time;
        requestWorld(req, resp, function(){
            if (0 == resp.code) {
                var rank = resp.data.rank;
                if (rank) {
                    var awardConf = gConfImperialExaminationAward[rank];
                    var score = awardConf.Score; 
                    activity.score += score;
                    player.saveActivityValue(key, 'score');
                    resp.data.score = score;
                }
            }
            onHandled && onHandled();
        });
        return;
    } while (false);

    onHandled && onHandled();
}

exports.shotmearrow_get = function(player, req, resp, onHandled) {
    do {
        var key = 'shotmearrow';
        var activity = player.getActivity(key, {conf:1, delay:1});
        if (!activity) {
            resp.code = 1; resp.desc = 'activity not open'; break;
        }

        activity = activity.data;

        var worldReq = {
            uid: req.uid,
            mod: 'activity',
            act: 'get_shotmearrow',
            args: {
                'time': activity.time
            }
        };
        requestWorld(worldReq, resp, function(){
            resp.data.activity = activity;
            onHandled && onHandled();
        });
        return;
    } while (false);

    onHandled && onHandled();
};

/**
 * 草船借箭-借箭
 * @param player
 * @param req
 * @param resp
 * @param onHandled
 */
exports.shotmearrow_shot = function(player, req, resp, onHandled) {
    var type = req.args.type;
    if (type == "one") {
        _shotOne(player, req, resp, onHandled);
    } else {
        _shotTen(player, req, resp, onHandled);
    }
};

/**
 * 获取排行榜
 * @param player
 * @param req
 * @param resp
 * @param onHandled
 */
exports.shotmearrow_getranks = function(player, req, resp, onHandled) {
    do {
        var key = 'shotmearrow';
        var activity = player.getActivity(key, {conf:1, delay:1});
        if (!activity) {
            resp.code = 1; resp.desc = 'activity not open'; break;
        }

        var worldReq = {
            uid: req.uid,
            mod: 'activity',
            act: 'get_shotmearrow_ranks',
            args: {
                'time': activity.time
            }
        };
        requestWorld(worldReq, resp, function(){
            var ranks = resp.data.ranks;
            var self = {};
            for (var _i=0; _i < ranks.length; _i++) {
                if (ranks[_i].uid == req.uid) {
                    self.rank = _i + 1;
                    self.data = ranks[_i];
                    break;
                }
            }
            resp.data.self = self;
            onHandled && onHandled();
        });
    } while (false);
};

/**
 * 积分商城购买
 * @param player
 * @param req
 * @param resp
 * @param onHandled
 */
exports.shotmearrow_buy = function(player, req, resp, onHandled) {
    do {
        var key = 'shotmearrow';
        var activity = player.getActivity(key, {conf:1, delay:1});
        if (!activity) {
            resp.code = 1; resp.desc = 'activity not open'; break;
        }

        var conf = activity.conf;
        activity = activity.data;

        // 检查参数
        var godId = +req.args.id;
        var godNum = +req.args.num;
        if (isNaN(godId) || isNaN(godNum) || (godNum <= 0)) {
            resp.code = 1; resp.desc = 'invalid argments'; break;
        }

        // 获取道具配置
        //var confId = conf.conf;
        //var shopConfig = gConfShotMeArrowShop[confId];
        var godConfig = gConfShotMeArrowShop[godId];
        if (!godConfig) {
            resp.code = 1; resp.desc = 'invalid argments'; break;
        }

        // 扣除积分
        var needPoint = +godConfig.Price * godNum;
        var havePoint = +activity.shotPoint;
        if (havePoint < needPoint) {
            resp.code = 1; resp.desc = 'no enough point'; break;
        } else {
            activity.shotPoint -= needPoint;
            player.saveActivityValue(key, 'shotPoint');
        }

        // 给玩家添加道具
        var rewards = _ensureAwards(godConfig.Award);
        var curNum = +rewards[0][2];
        rewards[0][2] = curNum * godNum;
        resp.data.awards = player.addAwards(rewards);
        resp.data.activity = activity;

    } while (false);

    onHandled && onHandled();
};

/**
 * 每日奖励领取
 * @param player
 * @param req
 * @param resp
 * @param onHandled
 */
exports.shotmearrow_dayreward = function(player, req, resp, onHandled) {
    do {
        var key = 'shotmearrow';
        var activity = player.getActivity(key, {conf:1});
        if (!activity) {
            resp.code = 1; resp.desc = 'activity not open'; break;
        }

        var conf = activity.conf;
        activity = activity.data;

        var wId = +req.args.id;
        if (isNaN(wId)) {
            resp.code = 1; resp.desc = 'invalid argments'; break;
        }

        // 获取道具配置
        var confId = conf.conf;
        var wConfig = gConfShotMeArrowReward[confId];
        var itemConfig = wConfig[wId];
        if (!itemConfig) {
            resp.code = 1; resp.desc = 'invalid argments'; break;
        }

        // 判断该奖励是否领取
        if (wId in activity.dayRewardArr) {
            // 奖励已经领取
            resp.code = 1; resp.desc = 'already get'; break;
        }

        // 获取当日全服借箭数
        var worldReq = {
            uid: req.uid,
            mod: 'activity',
            act: 'get_shotmearrow_shotNum',
            args: {
                'time': activity.time
            }
        };
        var wresp = {};
        requestWorld(worldReq, wresp, function(){
            do {
                var wShotNum = +wresp.data.shotNum;

                // 判断借箭数
                var needNum = +itemConfig.ArrowNum;
                if (wShotNum < needNum) {
                    resp.code = 1; resp.desc = 'server arrownum not fit'; break;
                }

                // 更新奖励状态
                activity.dayRewardArr[wId] = 1;
                activity.dayRewardTime = Date.getStamp();
                player.saveActivityValue(key, 'dayRewardTime');
                player.saveActivityValue(key, 'dayRewardArr');

                // 发放奖励
                var awards = _ensureAwards(itemConfig.Awards);
                resp.data.awards = player.addAwards(awards);
                resp.data.activity = activity;

            } while (false);
            onHandled && onHandled();
        });
        return;
    } while (false);
    onHandled && onHandled();
};

/**
 * 排名奖励
 * @param player
 * @param req
 * @param resp
 * @param onHandled
 */
exports.shotmearrow_rankreward = function(player, req, resp, onHandled) {
    do {
        var key = 'shotmearrow';
        var activity = player.getActivity(key, {conf:1, delay: 2});
        if (!activity) {
            resp.code = 1; resp.desc = 'activity not open'; break;
        }

        var conf = activity.conf;
        activity = activity.data;

        var wId = +req.args.id;
        if (isNaN(wId)) {
            resp.code = 1; resp.desc = 'invalid argments'; break;
        }

        // 获取奖励配置
        var confId = conf.conf;
        var wConfig = gConfShotMeArrowRankAward[confId];
        var itemConfig = wConfig[wId];
        if (!itemConfig) {
            resp.code = 1; resp.desc = 'invalid argments'; break;
        }

        // 判断该奖励是否领取
        if (activity.rankAwardTime != 0) {
            // 奖励已经领取
            resp.code = 1; resp.desc = 'already get'; break;
        }

        // 获取全服rank
        var worldReq = {
            uid: req.uid,
            mod: 'activity',
            act: 'get_shotmearrow_ranks',
            args: {
                'time': activity.time
            }
        };
        var wresp = {};
        requestWorld(worldReq, wresp, function(){
            do {
                var ranks = wresp.data.ranks;
                var rank = -1;
                for (var _i=0; _i < ranks.length; _i++) {
                    if (ranks[_i].uid == req.uid) {
                        rank = _i + 1;
                        break;
                    }
                }
                if (rank == -1 || rank > +gConfGlobal.ShotMeArrowRankSize) {
                    // 不在排行榜
                    resp.code = 1; resp.desc = 'not in ranks'; break;
                }

                var wrank = (itemConfig.Rank + "").split('|');
                if (wrank.length == 2) {
                    var minWRank = +wrank[0];
                    var maxWRank = +wrank[1];
                    if (rank < minWRank && rank > maxWRank) {
                        // 不能领取这奖励
                        resp.code = 1; resp.desc = 'not in award ranks'; break;
                    }
                } else if (wrank.length == 1) {
                    if (rank != +wrank[0]) {
                        // 不能领取这奖励
                        resp.code = 1; resp.desc = 'not in award ranks'; break;
                    }
                } else {
                    resp.code = 1; resp.desc = 'config error'; break;
                }

                // 更新活动数据
                activity.rankAwardTime = Date.getStamp();
                player.saveActivityValue(key, 'rankAwardTime');

                var awards = _ensureAwards(itemConfig.Awards);
                resp.data.awards = player.addAwards(awards);
                resp.data.activity = activity;
            } while (false);
            onHandled && onHandled();
        });
        return;
    } while (false);
    onHandled && onHandled();
};

/**
 * 借箭一次
 * @param player
 * @param req
 * @param resp
 * @param onHandled
 * @private
 */
function _shotOne(player, req, resp, onHandled) {
    do {
        var key = 'shotmearrow';
        var activity = player.getActivity(key, {conf:1});
        if (!activity) {
            resp.code = 1; resp.desc = 'activity not open'; break;
        }

        activity = activity.data;

        var cashCost = 0;

        // 判断是否达到最大免费借箭次数
        var curFreeShot = +activity.freeShotNum;
        var maxFreeShot = +gConfGlobal.ShotMeArrowFreeNum;
        if (curFreeShot >= maxFreeShot) {
            resp.code = 1; resp.desc = 'free shot limit'; break;
        }

        // 判断CD状态
        var lastShotTime = +activity.freeShotTime;
        if (lastShotTime != 0) {
            var freeShotCD = +gConfGlobal.ShotMeArrowFreeCD;
            var timePassed = Date.getStamp() - lastShotTime;
            var cdTime = freeShotCD * 60;
            if (timePassed <= cdTime) {
                // CD中，扣除玩家元宝
                if (!player.costResource('cash', +gConfGlobal.ShotMeArrowCleanCDCost)) {
                    resp.code = 1; resp.desc = 'cash not enough'; break;
                }
                cashCost = +gConfGlobal.ShotMeArrowCleanCDCost;
            }
        }

        // 计算获得积分
        var obj = __calcShotPoint(1);

        //更新活动数据
        activity.freeShotNum = activity.freeShotNum + 1; // 免费借箭+1
        activity.freeShotTime = Date.getStamp();
        activity.shotNum = activity.shotNum + 1; // 借箭次数+1
        activity.shotPoint = activity.shotPoint + obj.point;

        player.saveActivityValue(key, 'freeShotNum');
        player.saveActivityValue(key, 'freeShotTime');
        player.saveActivityValue(key, 'shotNum');
        player.saveActivityValue(key, 'shotPoint');

        // 广播暴击信息
        if ((+gConfGlobal.ShotMeArrowCritShowTip) == 1) {
            if (obj.critArr[0]) {
                gMessage.addSystemMessage('shotarrow_crit_one', [player.user.info.un, 1]);
            }
        }

        // 更新全服数据
        var worldReq = {
            uid: req.uid,
            mod: 'activity',
            act: 'update_shotmearrow',
            args: {
                'shotNum': activity.shotNum,
                'incV': 1,
                'un': player.user.info.un,
                'time': activity.time
            }
        };
        requestWorld(worldReq, resp, function(){
            resp.data.crit = obj.critArr;
            resp.data.activity = activity;
            resp.data.cash = -cashCost;
            onHandled && onHandled();
        });
        return;
    } while (false);

    onHandled && onHandled();
}

/**
 * 借箭十次
 * @param player
 * @param req
 * @param resp
 * @param onHandled
 * @private
 */
function _shotTen(player, req, resp, onHandled) {
    do {
        var key = 'shotmearrow';
        var activity = player.getActivity(key, {conf:1});
        if (!activity) {
            resp.code = 1; resp.desc = 'activity not open'; break;
        }

        var cashCost = 0;

        var conf = activity.conf;
        activity = activity.data;

        var confId = conf.conf;

        var curShotTenNum = +activity.shotTenNum + 1;
        var costConfig = gConfShotMeArrowCost[confId];
        var curCostConfig = costConfig[curShotTenNum];
        if (!curCostConfig) {
            var maxK = 0;
            var keys = Object.keys(costConfig);
            keys.forEach(function(v){
                if (maxK < +v) {
                    maxK = +v;
                }
            });
            curCostConfig = costConfig[maxK];
        }

        // 扣除玩家元宝
        if (!player.costResource('cash', +curCostConfig.Cost)) {
            resp.code = 1; resp.desc = 'cash not enough'; break;
        }

        cashCost = +curCostConfig.Cost;

        // 计算获得积分
        var obj = __calcShotPoint(10);

        //更新活动数据
        activity.shotTenNum = activity.shotTenNum + 1; // 借箭+1
        activity.shotNum = activity.shotNum + 10; // 借箭次数+10
        activity.shotPoint = activity.shotPoint + obj.point;

        player.saveActivityValue(key, 'shotTenNum');
        player.saveActivityValue(key, 'shotNum');
        player.saveActivityValue(key, 'shotPoint');

        // 广播暴击信息
        if ((+gConfGlobal.ShotMeArrowCritShowTip) == 1) {
            var critNum = 0;
            obj.critArr.forEach(function(crit){
                if (crit) {
                    critNum++;
                }
            });
            if (critNum > 0) {
                gMessage.addSystemMessage('shotarrow_crit_ten', [player.user.info.un, critNum]);
            }
        }

        // 更新全服数据
        var worldReq = {
            uid: req.uid,
            mod: 'activity',
            act: 'update_shotmearrow',
            args: {
                'shotNum': activity.shotNum,
                'incV': 10,
                'un': player.user.info.un,
                'time': activity.time
            }
        };
        requestWorld(worldReq, resp, function(){
            resp.data.crit = obj.critArr;
            resp.data.activity = activity;
            resp.data.cash = -cashCost;
            onHandled && onHandled();
        });
        return;
    } while (false);

    onHandled && onHandled();
}

/**
 * 计算借箭积分
 * @param num
 * @private
 */
function __calcShotPoint(num) {
    function calcPoint() {
        var isCrit = false;
        var getPoint = 0;
        var critChance = +gConfGlobal.ShotMeArrowCritChance;
        var crit = Math.floor(Math.random() * 100);
        if (crit <= critChance) {
            // 暴击
            isCrit = true;
            getPoint = +gConfGlobal.ShotMeArrowCritPoint;
        } else {
            var minGetPoint = +gConfGlobal.ShotMeArrowMinGetPoint;
            var maxGetPoint = +gConfGlobal.ShotMeArrowMaxGetPoint;
            var deltaPoint = maxGetPoint - minGetPoint;
            getPoint = Math.min(maxGetPoint, minGetPoint + deltaPoint * Math.random());
        }
        return {
            point: getPoint,
            crit: isCrit
        };
    }

    var critArr = [];
    var sumPoint = 0;

    for (var i=0; i<num; ++i) {
        var obj = calcPoint();
        sumPoint += Math.floor(obj.point);
        critArr.push(obj.crit);
    }

    return {
        critArr: critArr,
        point: sumPoint
    };
}

/**
 * 确保传递给addAwards函数的参数格式正确
 * @param awards
 * @returns {*}
 * @private
 */
function _ensureAwards(awards) {
    awards = JSON.parse(JSON.stringify(awards));
    if (awards instanceof Array) {
        var child = awards[0];
        if (child instanceof Array) {
            return awards;
        }
        return [awards];
    }
    return [];
}

/**
 * 领取日积月累奖励
 * @param player
 * @param req
 * @param resp
 * @param onHandled
 */
exports.daymonthpay_reward = function(player, req, resp, onHandled){
    do {
        var key = 'daymonthpay';
        var activity = player.getActivity(key, {conf:1, delay: 1 /* 整个活动过程可以领取奖励 */});
        if (!activity) {
            resp.code = 1; resp.desc = 'activity not open'; break;
        }

        var conf = activity.conf;
        activity = activity.data;

        // 要领取的奖励ID
        var wId = +req.args.id;
        if (isNaN(wId)) {
            resp.code = 1; resp.desc = 'invalid argments'; break;
        }

        // 获取奖励配置
        var confId = conf.conf;
        var wConfig = gConfDayMonthPayAward[confId];
        var itemConfig = wConfig[wId];
        if (!itemConfig) {
            resp.code = 1; resp.desc = 'invalid argments'; break;
        }

        // 判断该奖励是否领取
        if (activity.rewardMark.hasOwnProperty(wId)) {
            // 奖励已经领取
            resp.code = 1; resp.desc = 'already get'; break;
        }

        // 判断是否可以领取该奖励
        var needCash = itemConfig.Cash;
        if (activity.cash < needCash) {
            // 充值不够领取该奖励
            resp.code = 1; resp.desc = 'charge not reach'; break;
        }

        // 更新活动数据
        activity.rewardMark[wId] = Date.getStamp();
        player.saveActivityValue(key, 'rewardMark');

        // 发奖励
        var awards = _ensureAwards(itemConfig.Awards);
        resp.data.awards = player.addAwards(awards);
        resp.data.activity = activity;
    } while (false);

    onHandled && onHandled();
}

exports.treasuretravel_throw = function(player, req, resp, onHandled) {
    do {
        var key = 'treasuretravel';
        var activityInfo = player.getActivity(key, {conf:1});
        if (!activityInfo || !activityInfo.data) {
            resp.code = 1; resp.desc = 'activity not open'; break;
        }
        
        var confId = activityInfo.conf.conf;
        var activity = activityInfo.data;
        var costCash = 0;

        // 如果用光了免费次数，收费
        var throwTimes = player.getDailyVar('treasuretravel_times');
        if (throwTimes >= gConfGlobal.TreasureTravelFreeThrowTimes) { //付费投掷
            var confBuy = gConfBuy[throwTimes - gConfGlobal.TreasureTravelFreeThrowTimes + 1];
            costCash = (confBuy && confBuy.TreasureTravel) ? confBuy.TreasureTravel : gConfRuntime.TreasureTravelBuyMaxCost;
        }
        if(costCash && !player.costResource('cash', costCash)) {
            resp.code = 1; resp.desc = 'not enough cash';break;
        }

        var nextStartPos = activity.curPos % gConfRuntime.TreasureTravelPosMax + 1;
        var posConf = gConfTreasureTravel[confId][nextStartPos];
        activity.curPos = +common.wRand(posConf.PosWeights);
        player.saveActivityValue(key, 'curPos');

        posConf = gConfTreasureTravel[confId][activity.curPos];
        var posItem = +common.wRand(posConf.ItemWeights);

        // 加积分
        var scoreGet = 0;
        if (costCash > 0) {
            if (posConf.Type == 1) { // 收费宝箱
                scoreGet = +gConfGlobal.TreasureTravelCostChestThrowScore;
            } else { // 收费普通
                scoreGet = +gConfGlobal.TreasureTravelCostNormalThrowScore;
            }
            
            posItem = +common.wRand(posConf.PayItemWeights);
        } else {
            if (posConf.Type == 1) { // 免费宝箱
                scoreGet = +gConfGlobal.TreasureTravelChestThrowScore;
            } else { // 免费普通
                scoreGet = +gConfGlobal.TreasureTravelNormalThrowScore;
            }
        }
        activity.score += scoreGet;
        player.saveActivityValue(key, 'score');

        // 增加投掷次数
        player.addDailyVar('treasuretravel_times', 1);

        // 添加奖励
        var itemConf = gConfTreasureTravelItem[posItem];
        if (itemConf) {
            resp.data.awards = player.addAwards(itemConf.Awards)
        }
        resp.data.activity = activity;
        resp.data.cash = -costCash;
        resp.data.posItem = posItem;
    } while (false);

    onHandled && onHandled();
};

exports.treasuretravel_get_level_award = function(player, req, resp, onHandled) {
    do {
        var key = 'treasuretravel';
        var activityInfo = player.getActivity(key, {conf:1});
        if (!activityInfo || !activityInfo.data) {
            resp.code = 1; resp.desc = 'activity not open'; break;
        }

        var confId = activityInfo.conf.conf;
        var activity = activityInfo.data;
        var level = activity.levelAward;

        var levelConf = gConfTreasureTravelLevel[confId][level + 1];
        if (!levelConf) {
            resp.code = 1; resp.desc = 'got all'; break;
        }

        // 积分不够
        if (activity.score < +levelConf.Score) {
            resp.code = 1; resp.desc = 'can not get'; break;
        }

        activity.levelAward++;
        player.saveActivityValue(key, 'levelAward');
        resp.data.awards = player.addAwards(levelConf.Awards);
    } while (false);

    onHandled && onHandled();
}

exports.mailverify_get = function(player, req, resp, onHandled) {
    do {
        var path = util.format('mailverify_get.php?openid=%s', player.openid);
        requestGamex(path, resp, function() {
            if (!resp.code && !resp.data.code) {
                player.mailverify = resp.data.info || {};
            }
            onHandled && onHandled();
        });
        return;
    } while (false);

    onHandled && onHandled();
}

exports.mailverify_set = function(player, req, resp, onHandled) {
    do {
        if (!player.mailverify) {
            resp.code = 1; resp.desc = 'not get'; break;
        }
        
        var mail = req.args.mail;
        if (!mail || 'string' != typeof(mail) || mail.length > 30) {
            resp.code = 1; resp.desc = 'invalid args'; break;
        }

        var path = util.format('mailverify_set.php?openid=%s&mailto=%s', player.openid, mail);
        requestGamex(path, resp, function() {
            if (!resp.code && !resp.data.code) {
                player.mailverify = resp.data.info || {};
            }
            onHandled && onHandled();
        });
        return;
    } while (false);

    onHandled && onHandled();
}

exports.mailverify_verify = function(player, req, resp, onHandled) {
    do {
        if (!player.mailverify) {
            resp.code = 1; resp.desc = 'not get'; break;
        }
        
        var vcode = req.args.vcode;
        if (!vcode || 'string' != typeof(vcode) || vcode.length != 6) {
            resp.code = 1; resp.desc = 'invalid args'; break;
        }

        var path = util.format('mailverify_verify.php?openid=%s&vcode=%s', player.openid, vcode);
        requestGamex(path, resp, function() {
            if (!resp.code && !resp.data.code) {
                player.mailverify.status = 1;
            }
            onHandled && onHandled();
        });
        return;
    } while (false);

    onHandled && onHandled();
}

exports.mailverify_get_award = function(player, req, resp, onHandled) {
    do {
        if (!player.mailverify) {
            resp.code = 1; resp.desc = 'not get'; break;
        }

        var path = util.format('mailverify_award.php?openid=%s', player.openid);
        requestGamex(path, resp, function() {
            if (!resp.code && !resp.data.code) {
                player.mailverify.status = 2;
                resp.data.awards = player.addAwards(gConfGlobal.MailVerityAwards);
            }
            onHandled && onHandled();
        });
        return;
    } while (false);

    onHandled && onHandled();
}

exports.newyearsign_sign = function(player, req, resp, onHandled) {
    do {
        if (isNaN(req.args.day)) {
            resp.code = 1; resp.desc = 'invalid args'; break;
        }

        var key = 'newyearsign';
        var activityInfo = player.getActivityWithDelay(key, {conf:1});
        if (!activityInfo || !activityInfo.data) {
            resp.code = 1; resp.desc = 'activity not open'; break;
        }

        var activityConf = activityInfo.conf;
        var activity = activityInfo.data;

        var curDay = Date.getDayPassed(activityConf.time);
        var signDay = +req.args.day;

        if (activity.signDays[signDay]) {
            resp.code = 1; resp.desc = 'signed'; break;
        }

        var signConf = gConfNewYearSign[activityConf.conf][signDay];
        if (!signDay || signDay > curDay || !signConf) {
            resp.code = 1; resp.desc = 'invalid day'; break;
        }

        var costCash = 0;
        var signMark = 1; 
        if (signDay != curDay) {
            signMark = 2;
            var buyTimes = 0;
            objectForEach(activity.signDays, function(day, mark) {
                if (2 == mark) {
                    buyTimes++;
                }
            });

            var buyConf = gConfBuy[buyTimes + 1]; 
            if (!buyConf || !buyConf.NewYearSign) {
                resp.code = 1; resp.desc = 'no more to buy'; break;
            }

            costCash = +buyConf.NewYearSign;
            if (!player.costResource('cash', costCash, buyTimes)) {
                resp.code = 1; resp.desc = 'not enough cash'; break;
            }
        }

        activity.signDays[signDay] = signMark;
        player.saveActivityValue(key, 'signDays');

        resp.data.cash = -costCash;
        resp.data.awards = player.addAwards(signConf.Awards);
    } while (false);

    onHandled && onHandled();
}

exports.newyearsign_award = function(player, req, resp, onHandled) {
    do {
        var key = 'newyearsign';
        var activityInfo = player.getActivityWithDelay(key, {conf:1});
        if (!activityInfo || !activityInfo.data) {
            resp.code = 1; resp.desc = 'activity not open'; break;
        }

        var activityConf = activityInfo.conf;
        var activity = activityInfo.data;
        if (activity.award) {
            resp.code = 1; resp.desc = 'got'; break;
        }

        var signConf = gConfNewYearSign[activityConf.conf][0];
        var signDayCount = Object.keys(activity.signDays).length;
        if (signDayCount < signConf.MaxDay) {
            resp.code = 1; resp.desc = 'not reach'; break;
        }

        activity.award = 1;
        player.saveActivityValue(key, 'award');

        resp.data.awards = player.addAwards(signConf.Awards);
    } while (false);

    onHandled && onHandled();
}
